zoukankan      html  css  js  c++  java
  • 2019icpc西安邀请赛

    来源:https://www.jisuanke.com/contest/2625?view=challenges

    更新中

    A.Tasks

    直接贪心

    代码:听说当时很多队伍提前拆题甚至上机了,所以很多0min

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
         
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    #define lowbit(x) ((x)&(-x))
     
    using namespace std;
     
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
     
    const db eps = 1e-6;
    const int mod = 1e9+7;
    const int maxn = 1e6+100;
    const int maxm = 6e6+100;
    //const int inf = 0x3f3f3f3f;
    const int INF = 0x3f3f3f3f;
    const int MAXN = maxn;
    const int MAXM = maxm;
    const db pi = acos(-1.0);
    
    int n, t;
    int a[maxn];
    int main() {
        scanf("%d %d" ,&n ,&t);
        for(int i = 0; i < n; i++){
            scanf("%d", &a[i]);
        }
        sort(a,a+n);
        int tmp = 0;
        int ans = 0;
        for(int i = 0; i < n; i++){
            if(tmp+a[i]<=t){
                tmp+=a[i];ans++;
            }
    
        }printf("%d", ans);
        return 0;
    }
    View Code

    C.Angel's Journey

    题意:给定一个圆的圆心(rx, ry),半径r,A的坐标(rx, ry-r),B的坐标(x, y),y>ry,只能走圆上以及圆外y>ry的地方,求A到B的最短路

    思路:当x<rx-r或x>rx+r的时候直接从半圆的地方走直线,否则在圆弧上走到切点然后走直线

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
         
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    #define lowbit(x) ((x)&(-x))
     
    using namespace std;
     
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
     
    const db eps = 1e-6;
    const int mod = 1e9+7;
    const int maxn = 1e6+100;
    const int maxm = 6e6+100;
    //const int inf = 0x3f3f3f3f;
    const int INF = 0x3f3f3f3f;
    const int MAXN = maxn;
    const int MAXM = maxm;
    const db pi = acos(-1.0);
    
    int n, t;
    int a[maxn];
    int main() {
        double rx,ry,r,x,y;
        int t;
        scanf("%d" ,&t);
        while(t--){
            scanf("%lf %lf %lf %lf %lf", &rx,&ry,&r,&x,&y);
    
            double ob = sqrt((x-rx)*(x-rx)+(y-ry)*(y-ry));
            double ans = sqrt(ob*ob-r*r)+r*(pi/2.0+asin((y-ry)/ob)-acos(r/ob));
            if(x<rx-r||x>rx+r){
                if(x<rx-r)rx-=r;
                if(x>rx+r)rx+=r;
                ans=pi/2+sqrt((x-rx)*(x-rx)+(y-ry)*(y-ry));
            }
            printf("%.4lf
    ",ans);
        }
        return 0;
    }
    View Code

    D.Miku and Generals

    题意:n个数,还有m对矛盾的数,n,m<=200,a[i]<=5e4&&(a[i]%100==0),矛盾的不能放在一堆,让你分配这两堆数(都要用完),使得两堆数的和之差最小,输出那个最大的数

    思路:将矛盾的值连无向边,因为答案是保证存在的,所以对每一个连通块只有两种选法,通过dfs染色把它们提出来,就是一个背包了,由于a[i]%100==0,所以先除了最后再补俩零也不影响

    代码:我tm最后才发现那个a[i]能整除100。。复杂度downdown

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
         
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    #define lowbit(x) ((x)&(-x))
     
    using namespace std;
     
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
     
    const db eps = 1e-6;
    const int mod = 1e9+7;
    const int maxn = 1e7+100;
    const int maxm = 6e6+100;
    const int inf = 0x3f3f3f3f;
    const db pi = acos(-1.0);
    
    int n, m;
    vector<int>v[maxn/100];
    int vis[maxn/100];
    int a[maxn/100];
    int f[maxn];
    
    void dfs(int x, int fa, int faa, int co){
        if(vis[x]!=-1)return;
        if(co){
            if(x!=fa){a[fa]+=a[x];a[x]=-1;}
            vis[x]=fa;
        }
        else{
            if(x!=faa){a[faa]+=a[x];a[x]=-1;}
            vis[x]=faa;
        }
        int t;
        if(x==fa&&v[x].size()>0)t = v[x][0];
        else t=faa;
        for(int i = 0; i < (int)v[x].size(); i++){
            int y = v[x][i];
            if(vis[y]==-1){
                dfs(y,fa,t,co^1);
            }
    
        }
    }
    bool cmp(int a,int b){return a>b;}
    int main() {
        int t;
        scanf("%d" ,&t);
        int ncase = 0;
        while(t--){
            scanf("%d %d" ,&n, &m);
            //mem(f,0);
            ncase++;
            int sum = 0;
            for(int i = 1; i <= n; i++){
                v[i].clear();
                vis[i]=-1;
                scanf("%d", &a[i]);a[i]/=100;sum+=a[i];
            }
            for(int i = 1; i <= m; i++){
                int x,y;
                scanf("%d %d" ,&x, &y);
                v[x].pb(y);
                v[y].pb(x);
            }
            for(int i = 1; i <= n; i++){
                if(vis[i]==-1){
                    dfs(i,i,0,1);
                }
            }
            sort(a+1,a+1+n,cmp);
            int ans=0;
            f[0]=ncase;
            for(int i = 1; i <= n; i++){
                if(a[i]==-1)break;
                for(int j = sum; j >= 0; j--){
                    if(j-a[i]>=0&&f[j-a[i]]==ncase){
                        //printf("  %d  
    ",j);
                        f[j]=ncase;
                        if(j<=sum/2)ans=max(ans,j);
                    }
                }
            }
            printf("%d00
    ",sum-ans);
        }
        
        return 0;
    }
     
    View Code

    J.And And And

    题意:一棵有边权的树,对每一对(u,v),如果u到v路径上边权异或和为0,则它对答案的贡献为包含这条路径的树上路径数量,求总答案

    思路:以1为根,预处理出各个子树的size,对每一对满足条件的(u,v),因为树上的路径是唯一的,它的贡献应该是u除这条路径外能走的点数*v除这条路径外能走的点数,当u和v在不同链上的时候,答案就是size[u]*size[v];若u和v在同一条链上,其中一个点(例如v)如果是深度较大的点,那么后者就是size[v],前者可以动态统计。

    于是可以直接dfs,因为dfs的时候走下来就是一条链,回溯之后就是另一条链,所以在处理同一条链的时候我们可以统计当前点为u时的贡献即可。不同链的时候,我们让它dfs到底,当当前点处理完之后,说明这条链搞完了,就可以一条链一条链更新了,这个看代码好像比较好理解。。。

    对了,u到v路径异或和为0可以转化为到根的异或和相等。

    代码:long long很烦,而且深搜好像并不需要记录fa。。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
    #include<unordered_map>
         
    #define fst first
    #define sc second
    #define pb push_back
    #define mp make_pair
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    #define lowbit(x) ((x)&(-x))
     
    using namespace std;
     
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
     
    const db eps = 1e-6;
    const int mod = 1e9+7;
    const int maxn = 1e5+100;
    const int maxm = 6e6+100;
    const int inf = 0x3f3f3f3f;
    const db pi = acos(-1.0);
    
    int n;
    vector<pair<int,ll> >v[maxn];
    int sz[maxn];
    void dfsInit(int x, int fa){
        sz[x]++;
        for(int i = 0; i < (int)v[x].size(); i++){
            int y = v[x][i].fst;
            if(y!=fa){
                dfsInit(y,x);
                sz[x]+=sz[y];
            }
        }
    }
    ll ans;
    unordered_map<ll,int> num;// the value of gongxian in sta == i
    ll tmp;
    void dfs1(int x, int fa, ll sum){//the same line
        ans += 1ll*num[sum]*sz[x];
        ans%=mod;
        for(int i = 0; i < (int)v[x].size(); i++){
            int y = v[x][i].fst;
            ll w = v[x][i].sc;
            if(y!=fa){
                tmp=(tmp+sz[x]-sz[y]+mod)%mod;
                num[sum]=(num[sum]+tmp)%mod;
                dfs1(y,x,sum^w);
                num[sum]=(num[sum]-tmp+mod)%mod;
                tmp=(tmp-(sz[x]-sz[y])+mod)%mod;
            }
        }
    }
    void dfs2(int x, int fa, ll sum){
        ans += 1ll*num[sum]*sz[x];
        ans%=mod;
        for(int i = 0; i < (int)v[x].size(); i++){
            int y = v[x][i].fst;
            ll w = v[x][i].sc;
            if(y==fa)continue;
            dfs2(y,x,sum^w);
        }
        num[sum]+=sz[x];
        num[sum]%=mod;
    }
    int main() {
        tmp=ans=0;
        scanf("%d" ,&n);
        for(ll i = 2; i <= n; i++){
            int x;
            ll w;
            scanf("%d %lld", &x, &w);
            v[x].pb(mp(i,w));
            v[i].pb(mp(x,w));
        }
        dfsInit(1,0);
        dfs1(1,0,0);
        num.clear();
        dfs2(1,0,0);
        printf("%lld",ans);
        return 0;
    }
    View Code

    L.Swap

    题意:一个排列可以交换前n/2与后n/2,或前n^1个数奇数位置和偶数位置交换,问通过这两个操作最多产生多少个不同的排列

    思路:打表发现从第五项开始是2n, n, 12, 4的规律。或者直接交上打表的模拟,由于只有两条链,而且只有一组数据,也能过

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
         
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    #define lowbit(x) ((x)&(-x))
     
    using namespace std;
     
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
     
    const db eps = 1e-6;
    const int mod = 1e9+7;
    const int maxn = 1e6+100;
    const int maxm = 6e6+100;
    const int inf = 0x3f3f3f3f;
    const db pi = acos(-1.0);
    
    int n;
    int a[maxn],b[maxn];
    int ans;
    void gao1(int a[]){
        int l = 1;
        int r = n/2+1;
        if(n&1)r++;
        for(int i = 1; i <= n/2; i++){
            swap(a[l+i-1],a[r+i-1]);
        }
        return;
    }
    void gao2(int a[]){
        for(int i = 1; i+1 <= n; i+=2){
            //printf("  %d %d %d
    ",i,a[i],a[i+1]);
            swap(a[i],a[i+1]);
        }
        return;
    }
    
    int sv(int n){
        ::n=n;
        ans=1;
        int sta=1;
        for(int i = 1; i <= n; i++)a[i]=b[i]=i;
        /*if(n==1)return 1;
        if(n==2)return 2;
        if(n==3)return 6;*/
        gao1(a);gao2(b);
        //for(int i = 1; i <= n; i++)printf("%d ",a[i]);printf("
    ");
        //for(int i = 1; i <= n; i++)printf("%d ",b[i]);printf("
    ");
        while(1){
            //for(int i = 1; i <= n; i++)printf("%d ",a[i]);printf("
    ");
            //for(int i = 1; i <= n; i++)printf("%d ",b[i]);printf("
    ");
            int ys = 0;
            sta^=1;
            for(int i = 1; i <= n; i++){
                if(a[i]!=b[i])ys=1;
            }
            if(!ys){
                ans++;break;
            }
            else{
                ans+=2;
                if(sta) {gao1(a);gao2(b);}
                else {gao1(b);gao2(a);}
            }
        }
        return ans;
    }
    int main() {
        //scanf("%d" ,&n);
        //sv(3);
        for(int i = 1; i <= 100; i++){
            printf("%d %d
    ",i,sv(i));
        }
        scanf("%d", &n);
        //for(int i = 1; i <= n; i++)scanf("%d", &a[i]);
            printf("%d",sv(n));
        return 0;
    }
    View Code

     M.Travel

    题意:一个有边权的无向图,刚开始无边可走,每次操作可以增加e条边,增加d点能量,每次操作花费c,问从1走到n最少花费多少,只有这条边加了并且能量不小于边权才能走

    思路:我第n次sb。。很明显的二分,而我妄图一次dijk搞完,就把自己搞完了。

    很显然操作次数具有单调性,并且因为保证联通,所以答案一定存在。

    代码:因为改了很多次,所以很丑

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
         
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    #define lowbit(x) ((x)&(-x))
     
    using namespace std;
     
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
     
    const db eps = 1e-6;
    const int mod = 1e9+7;
    const int maxn = 1e6+100;
    const int maxm = 6e6+100;
    const int inf = 0x3f3f3f3f;
    const db pi = acos(-1.0);
    
    int vis[maxn];
    struct node{
        int id,w;
        node(int a, int b){id=a;w=b;}
        bool operator < (const node & a) const{
            return w>a.w;
        }
    };
    vector<node>v[maxn];
    int n,m;
    int c, d, e;
    bool ck(int k){
        //printf(" %d
    ",k);
        for(int i = 1; i <= n; i++)vis[i]=0;
        queue<PI>q;
        q.push(make_pair(1,0));
        while(!q.empty()){
            PI top = q.front();q.pop();
            int x = top.fst;
            int d = top.sc;
            //printf("%d %d  ----%d
    ",x,d);
            if(x==n){
                if(d<=1ll*e*k)return true;
                else return false;
            }
            if(vis[x])continue;
            vis[x]=1;
            for(int i = 0; i < (int)v[x].size(); i++){
                node y = v[x][i];
                //printf("  %d %d
    ",y.id,y.w);
                if(!vis[y.id]&&1ll*y.w<=1ll*(::d)*k)q.push(make_pair(y.id,d+1));
            }
        }
        return false;
    }
    int main() {
        
        scanf("%d %d", &n, &m);
        scanf("%d %d %d" ,&c, &d, &e);
        for(int i = 1; i <= m; i++){
            int x,y,w;
            scanf("%d %d %d" ,&x, &y, &w);
            v[x].pb(node(y,w));
            v[y].pb(node(x,w));
        }
        int l, r;
        l = 0; r = 1e5+100;
        int ans = -1;
        while(l<=r){
            int mid = (l+r)>>1;
            if(ck(mid)){
                ans = mid;
                r=mid-1;
            }
            else l= mid+1;
        }
        printf("%lld",1ll*c*ans);
        return 0;
    }
    /*
    3 3
    1 99 1 
    1 2 100
    1 3 100
    2 3 2
     */
    View Code
  • 相关阅读:
    TStringList 常用操作(转自南山古陶)
    在Delphi中使用Indy控件实现邮件群发
    GSM手机SMS编码解码
    建别人进不了删不掉的文件夹
    播放 wav 文件
    delphi inherited,纯虚
    PDU编码规则
    sql函数
    基于GPRS的LED电子显示屏
    结对编程 队友代码分析
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/10969993.html
Copyright © 2011-2022 走看看