2018中国大学生程序设计竞赛 - 网络选拔赛

传送门

A.HDU6438 Buy and Resell

题意

给你N天N个价格,每天都可以从1.买入一个,2.卖出一个,3.什么都不做,求最高获利

低买高卖问题,这题与其他的差距就是要在满足获利最多的情况下,买卖次数最小;

思路

手算一下发现价格具有传递性;例如数据是1,5,9;
5的时候买入1赚了4;9的时候买入5赚了4;相当于直接把5当成跳板直接9的时候买1;然后再把中间的5当成没有买过的;

建立一个小根堆(优先队列);把当前遇到的天数的价钱放入,然后对于第i天;

1.如果新天数的价钱比堆顶小;说明交易亏本,直接丢入堆中;
2.如果价钱高说明有赚头;
2.1.如果堆顶的是已经跟之前的交易过的,那相当于当前天和之前的那个交易,然后堆顶的变成没有交易的;继续插入;交易次数不变
2.2否则直接交易,交易次数+2

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=1e6+50;
const ll inf=0x3f3f3f3f3f3f;
int a[maxn];
struct node{
    int id;
    int money;
    bool has;
    node(int id,int money,bool has):id(id),money(money),has(has){}
    bool friend operator <(node a,node b){
        if(a.money==b.money)return a.has<b.has;
        return a.money>b.money;
    }
};
int flag[maxn];
int used[maxn];
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        ll ans=0;
        ll cnt=0;
        memset(flag,0,sizeof(flag));
        memset(used,-1,sizeof(used));
        for(int i=0;i<n;i++)cin>>a[i];
        priority_queue<node>pq;
        for(int i=0;i<n;i++){
            if(pq.empty())pq.push(node(i,a[i],0));
            else{
                node now=pq.top();
                if(now.money>=a[i])pq.push(node(i,a[i],0));
                else{
                    pq.pop();
                    if(flag[now.id]){
                        ans+=a[i]-now.money;
                        flag[i]=1;flag[now.id]=0;
                        used[i]=used[now.id];
                        used[now.id]=-1;
                        pq.push(node(i,a[i],1));
                        pq.push(node(now.id,a[now.id],0));
                    }
                    else{
                        ans+=a[i]-now.money;
                        cnt+=2;
                        flag[i]=1;flag[now.id]=1;
                        used[i]=now.id;
                        pq.push(node(i,a[i],1));
                    }
                }
            }
        }
        cout<<ans<<" "<<cnt<<endl;
    }
    return 0;
}

C.HDU6440 Dream

题意

对一个质数P,对小于P的非负数定义一种乘法和加法运算,使得其满足封闭性,且对于存在一个数q使得{qk|0< k< p}

思路

费马小定理,比赛随便迷一样的试了一下就A了,自己也不知道怎么解释...

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=1e5+50;
const ll inf=0x3f3f3f3f3f3f;
int n;
int vis[maxn];
int size[maxn];
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int t;
    cin>>t;
    while(t--){
        int p;
        cin>>p;
        for(int i=0;i<p;i++){
            cout<<i;
            for(int j=1;j<p;j++){
                cout<<" "<<(i+j)%p;
            }
            cout<<endl;
        }

        for(int i=0;i<p;i++){
            cout<<0;
            for(int j=1;j<p;j++){
                cout<<" "<<(i*j)%p;
            }
            cout<<endl;
        }

    }
    return 0;
}

D.HDU6441 Find Integer

题意

题意:已知a^n+b^n=c^n,给出n和a,求b,c,如果无解输出?1。

思路

费马大定理

  1. a^n+b^n=c^n,n>2时无解。
  2. 当a为奇数时,
    a=2?k+1
    c=k^2+(k+1)^2
    b=c?1
    3.当 a 为偶数
    a=2?k+2
    c=1+(k+1)^2
    b=c?2
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=3e6+50;
const ll inf=0x3f3f3f3f3f3f;

int main()
{
    //std::ios::sync_with_stdio(false);
   // std::cin.tie(0);
    //std::cout.tie(0);
    int t;
    scanf("%d",&t);
    while(t--){
        ll n,a;
        scanf("%lld%lld",&n,&a);
        if(n==0){
            printf("-1 -1\n");
        }
        else if(n==1){
            printf("1 %lld\n",a+1);
        }
        else if(n==2)
            {
                if(a&1){
                    printf("%lld %lld\n",a*a/2,a*a/2+1);
                }
                else{
                    printf("%lld %lld\n",(a/2)*(a/2)-1,(a/2)*(a/2)+1);
                }
            }
        else{
            printf("-1 -1\n");
        }
    }
    return 0;
}

I.HDU6446 Tree and Permutation

题意

题意:给你一颗树,然后让你求n!种序列中,所以得序列和,序列和定义为:A1,A2,A3……AN=A1A2+A2A3+…….An-1An

思路

首先,对于题目给出的n-1条边,我们可以这样考虑,去掉这条边后,将树分成了两部分,一部分有M个节点,另一部分有(N-M)个节点,所以我们必须在这两块中任意选择一个节点才会进过这条边,所以,有N × M× 2 中选择,然后又N!个序列所以对于E这条边,一共又2×N×M×(N-1)!×L的贡献。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=1e5+50;
const ll inf=0x3f3f3f3f3f3f;
int n;
int vis[maxn];
int size[maxn];
struct Edge{
    int to;
    int s;
    int t;
    int l;
    Edge(int to,int s,int t,int l):to(to),s(s),t(t),l(l){}
};
ll f[maxn];
int init(){
    f[0]=1;f[1]=1;
    for(int i=2;i<=100000;i++)f[i]=(f[i-1]*i)%mod;
}
ll ans;
vector<Edge>G[maxn];
void dfs(int u){
    vis[u]=1;
    int cnt=1;
    for(int i=0;i<G[u].size();i++){
        Edge &e=G[u][i];
        if(vis[e.to]==0){
            dfs(e.to);
            ll tmp=size[e.to];
            tmp=tmp*(n-tmp)%mod;
            tmp=tmp*2%mod;
            tmp=tmp*e.l%mod;
            tmp=tmp*f[n-1]%mod;
            ans+=tmp;
            ans%=mod;
            cnt+=size[e.to];
        }
    }
    size[u]=cnt;
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int t;
    init();
    while(cin>>n){
        for(int i=0;i<=n;i++)G[i].clear();
        for(int i=0;i<=n;i++)size[i]=0,vis[i]=0;
        ans=0;
        for(int i=0;i<n-1;i++){
            ll x,y,l;
            cin>>x>>y>>l;
            G[x].push_back(Edge(y,x,y,l));
            G[y].push_back(Edge(x,x,y,l));
        }
        dfs(1);
        cout<<ans<<endl;
    }
    return 0;
}

J.HDU6447 YJJ‘s Salesman

题意

题意:一个地图,里面有最多1e5个村庄,YJJ从0,0开始走,只能向左,下,左下走,如果向左下走进一个村庄那就能获得这个村庄的价值;求最大价值;从(0,0)到(n,n);
数据范围1e9!数组装不下

思路

首先题意是求最大值,最基本的DP模型是三个方向的最大值;但是复杂度会爆炸而且也开不了那么大的数组;
1.离散化坐标;因为1e9的坐标范围太大数组装不下,但是只有1e5的村庄,所以可以把1e9离散化到1e5里面;

2.每次搜索前面的最大值;利用树状数组搜索到当前位置的J坐标之前的最大值然后加上当前值再添加进树状数组

比赛的时候离散完,想吧坐标压缩成一维的可是没想到办法所以凉凉了,其实这题不用压缩直接按照x的坐标从小到大排序,然后按照同一行从大到小排序就行了;

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=1e5+50;
const int maxm=1e5+50;
const ll inf=0x3f3f3f3f3f3f;
int N;
struct node{
    int x,y,value;
};
int cmp(node a,node b){
    if(a.x==b.x)return a.y>b.y;
    return a.x<b.x;
}
int c[maxm];
inline int lowbit(int x){return x&(-x);}
void update(int x,int p){
    for(int i=x;i<maxn;i+=lowbit(i)){
        c[i]=max(c[i],p);
    }
}
int query(int x){
    int ma=0;
    for(int i=x;i>0;i-=lowbit(i)){ma=max(ma,c[i]);}
    return ma;
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        vector<node>ve;
        vector<int>k;
        k.push_back(-1);
        memset(c,0,sizeof(c));
        for(int i=0;i<n;i++){
            node a;
            cin>>a.x>>a.y>>a.value;
            ve.push_back(a);
            k.push_back(a.y);
        }
        sort(k.begin(),k.end());
        sort(ve.begin(),ve.end(),cmp);
        k.erase(unique(k.begin(),k.end()),k.end());
        N=k.size();
        int anw=0;
        for(int i=0;i<n;i++){
            int ans=lower_bound(k.begin(),k.end(),ve[i].y)-k.begin();
            int cnt=query(ans-1);
            cnt+=ve[i].value;
            update(ans,cnt);
            anw=max(anw,cnt);
        }
        cout<<anw<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/luowentao/p/10332188.html

时间: 2024-11-08 00:51:25

2018中国大学生程序设计竞赛 - 网络选拔赛的相关文章

HDU6447 YJJ&#39;s Salesman 2018中国大学生程序设计竞赛 - 网络选拔赛1010 离散化+线段树+DP

YJJ's Salesman Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 253    Accepted Submission(s): 62 Problem Description YJJ is a salesman who has traveled through western country. YJJ is always on

2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ&#39;s Salesman 【离散化+树状数组维护区间最大值】

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 919    Accepted Submission(s): 290 Problem Description YJJ is a salesman who h

2018中国大学生程序设计竞赛 - 网络选拔赛 hdu6438 Buy and Resell 买入卖出问题 贪心

Buy and Resell Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1126    Accepted Submission(s): 359 Problem Description The Power Cube is used as a stash of Exotic Power. There are n cities numbe

2018中国大学生程序设计竞赛 - 网络选拔赛 Dream hdu6440 Dream 给出一个(流氓)构造法

http://acm.hdu.edu.cn/showproblem.php?pid=6440 题意:让你重新定义任意一对数的乘法和加法结果(输出乘法口诀表和加法口诀表),使得m^p+n^p==(m+n)^p(p为质数),并且存在一个0<q<p使得 q^k(0<k<p)取遍1~p-1的所有值,并且该运算是封闭的(exists an integer q(0<q<p) to make the set {qk|0<k<p,k∈Z} equal to {k|0<

2017中国大学生程序设计竞赛 - 网络选拔赛 HDU 6154 CaoHaha&#39;s staff 思维

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6154 题意:在笛卡尔坐标系下,画一个面积至少为  n 的简单多边形,每次只能画一条边或者一个格子的对角线,问至少要画几条. 解法:如果一个斜着的矩形长宽分别是 a,b,那么它的面积是 2ab.最优解肯定是离 sqrt(n/2)很近的位置.想想 n=5 时答案为什么是7 然后在那个小范围内枚举一下就好了.我给一张做题时画的图 #include <bits/stdc++.h> using namesp

2016中国大学生程序设计竞赛 - 网络选拔赛

solved 4/11 2016中国大学生程序设计竞赛 - 网络选拔赛

HDU 5833 Zhu and 772002(高斯消元)——2016中国大学生程序设计竞赛 - 网络选拔赛

传送门 Zhu and 772002 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 48    Accepted Submission(s): 16 Problem Description Zhu and 772002 are both good at math. One day, Zhu wants to test the abili

HDU 5832 A water problem(取模~)—— 2016中国大学生程序设计竞赛 - 网络选拔赛

传送门 A water problem Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 60    Accepted Submission(s): 37 Problem Description Two planets named Haha and Xixi in the universe and they were created wit

2017中国大学生程序设计竞赛 - 网络选拔赛 HDU 6154 CaoHaha&#39;s staff(几何找规律)

Problem Description "You shall not pass!"After shouted out that,the Force Staff appered in CaoHaha's hand.As we all know,the Force Staff is a staff with infinity power.If you can use it skillful,it may help you to do whatever you want.But now,hi