• Codeforces Round #580 (Div. 2)


    Solutions


    A. Choose Two Numbers

    题意:
    给出(A,B)两个集合,(A,B) 集合分别选一个数(a,b) ,使得(a+b otin A,B)
    思路:
    每个集合选出最大值,必定满足条件。emmmmm比赛的时候傻了。

    //#define DEBUG
    #include<bits/stdc++.h>
    using namespace std;
    #define lson (rt<<1)
    #define rson (rt<<1|1)
    const int N=100010;
    const int inf=0X3f3f3f3f;
    const long long INF = 0x3f3f3f3f3f3f3f3f;
    const double eps = 1e-6;
    const double pi = acos(-1.0);
    const int mod = 1000000007;
    typedef long long ll;
    
    int a[110];
    int main() {
    	#ifdef DEBUG
    	freopen("in.txt","r",stdin);
    	#endif
        int n,m,ans1,ans2;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        ans1=*max_element(a+1,a+n+1);
        scanf("%d",&m);
        for(int i=1;i<=m;i++) scanf("%d",&a[i]);
        ans2=*max_element(a+1,a+m+1);
        printf("%d %d
    ",ans1,ans2);
    }
    
    

    B. Make Product Equal One

    题意:
    给出(a_1,a_2,dots,a_n),可以进行任意次操作:选择其中任意一个数(+1,-1),使得最后(a_1{ast}a_2{ast}dots{ast}a_n=1)
    思路:
    负数就变为(-1),整数就变为(1),但是若负数个数为奇数,则需要有一个变为(1),但是存在(0)的话,则不需要。

    //#define DEBUG
    #include<bits/stdc++.h>
    using namespace std;
    #define lson (rt<<1)
    #define rson (rt<<1|1)
    const int N=100010;
    const int inf=0X3f3f3f3f;
    const long long INF = 0x3f3f3f3f3f3f3f3f;
    const double eps = 1e-6;
    const double pi = acos(-1.0);
    const int mod = 1000000007;
    typedef long long ll;
     
    int main() {
    	#ifdef DEBUG
    	freopen("in.txt","r",stdin);
    	#endif
        int n;
        scanf("%d",&n);
        ll ans=0,ok=0,res=1;
        for(int i=1;i<=n;i++) {
            int x;
            scanf("%d",&x);
            if(x>=1) ans+=x-1;
            else if(x<0) ans+=-1-x,res*=-1;
            else if(!x) ans+=1,ok=1;
        }
        if(ok||res==1) printf("%lld
    ",ans);
        else printf("%lld
    ",ans+2);
    }
    

    C. Almost Equal

    题意:
    给出数字(n),你需要安排的数为(1sim2n),组成一个环。每连续(n)个数求一次和(sum_i),输出一个合法的序列,使得({forall}i,j, {mid}sum_i-sum_j{mid}{leq}1)
    思路:
    比赛时我构造出序列,然后队友写出(check) 代码,构造时发现分为两部分,右边最上面写一个最大的,左边最下面写次大的,然后左边再写次次大的,右边再写次次次大的,交替进行。可以理解为右边为先手,然后左边变为先手。构造完以后,用数组模拟成环,然后前缀和搞一搞模拟(check) 即可。
    正解:
    我们定义(s_i=a_i+a_{i+1}+a_{i+2}+{dots}+a_{i+n-1})
    (S_{i+1}-S_{i}=left(a_{i+1}+a_{i+2}+a_{i+3}+cdots+a_{i+n} ight)-left(a_{i}+a_{i+1}+a_{i+2}+cdots+a_{i+n-1} ight)=a_{i+n}-a_{i}) 根据题意有({mid}a_{i+n}-a_i{mid}{leq}1),因为(a)数组都是不同的,所以({mid}a_{i+n}-a_i{mid}=1)
    则根据题意有:(a_{i+n}-a_i,a_{i+n+1}-a_{i+1}) 有相反的符号。 证:若他们都等于(1),则(S_{i+2}-S_i=(S_{i+2}-S_{i+1})+(S_{i+1}-S_{i})=(a_{i+n+1}-a_{i+1})+(a_{i+n}-a_i)=2),若都为(-1)也一样。因此,对于(a_{i+n}-a_i),他们是交替的(1,-1,1,dots)

    • 如果(n)为偶数,存在矛盾(a_{i+n}-a_i=-(a_{(i+n)+n}-a_{i+n})),但是由于交替,所以他们应该是相等的
    • 如果(n)为奇数,(i:1{sim}n)
      • (i)为奇数,(a_i=2i,a_{i+n}=2i-1)
      • (i)为偶数,(a_i=2i-1,a_{i+n}=2i)
    //#define DEBUG
    #include<bits/stdc++.h>
    using namespace std;
    #define lson (rt<<1)
    #define rson (rt<<1|1)
    const int N=100010;
    const int inf=0X3f3f3f3f;
    const long long INF = 0x3f3f3f3f3f3f3f3f;
    const double eps = 1e-6;
    const double pi = acos(-1.0);
    const int mod = 1000000007;
    typedef long long ll;
    
    int a[N],b[N],c[4*N];
    ll ans[4*N];
    int main() {
    	#ifdef DEBUG
    	freopen("in.txt","r",stdin);
    	#endif
        int n;
        scanf("%d",&n);
        bool flag=true;
        int cura=0,curb=0;
        int x=2*n;
        while(x) {
            if(flag) {
                b[++curb]=x--;
                a[++cura]=x--;
            } else {
                a[++cura]=x--;
                b[++curb]=x--;
            }
            flag=!flag;
        }
        int cur=0;
        for(int i=cura;i>=1;i--) c[++cur]=a[i];
        for(int i=curb;i>=1;i--) c[++cur]=b[i];
        int len=cur;
        for(int i=1;i<=len;i++) c[++cur]=c[i];
        //for(int i=1;i<=cur;i++) printf("%d
    ",c[i]);
        set<ll> s;
        for(int i=1;i<=n;i++)ans[i]=ans[i-1]+c[i];
    	s.insert(ans[n]);
    	for(int i=n+1;i<=3*n;i++){
    		ans[i]=ans[i-1]-c[i-n]+c[i];
    		s.insert(ans[i]);
    	}
    	if(s.size()>2)puts("NO");
    	else if(s.size()==2){
    		set<ll>::iterator it=s.begin();
    		ll s1,s2;
    		s1=*it;
    		it++;
    		s2=*it;
    		if(abs(s1-s2)!=1)puts("NO");
    		else {
                puts("YES");
    			for(int i=1;i<=2*n;i++)printf("%d%c",c[i],i==2*n?'
    ':' ');
    		}
    	}
    	else {
    	    puts("YES");
    		for(int i=1;i<=2*n;i++)printf("%d%c",c[i],i==2*n?'
    ':' ');
    	}
    }
    
    
    //#define DEBUG
    #include<bits/stdc++.h>
    using namespace std;
    #define lson (rt<<1)
    #define rson (rt<<1|1)
    const int N=100010;
    const int inf=0X3f3f3f3f;
    const long long INF = 0x3f3f3f3f3f3f3f3f;
    const double eps = 1e-6;
    const double pi = acos(-1.0);
    const int mod = 1000000007;
    typedef long long ll;
    
    int a[2*N];
    int main() {
    	#ifdef DEBUG
    	freopen("in.txt","r",stdin);
    	#endif
        int n;
        scanf("%d",&n);
        if(n%2==0) {puts("NO");return 0;}
        puts("YES");
        for(int i=1;i<=n;i++) {
            if(i&1) a[i]=2*i,a[i+n]=2*i-1;
            else a[i]=2*i-1,a[i+n]=2*i;
        }
        for(int i=1;i<=2*n;i++) printf("%d%c",a[i],i==2*n?'
    ':' ');
    }
    
    

    D. Shortest Cycle

    题意:
    给出(a_1,a_2,{dots},a_n),当作图中的(n)个点,对于({forall}i,j(i{ eq}j),a_i&a_j{ eq}0)(a_i)(a_j)连一条边,然后求最小环。
    思路:
    比赛时队友考虑二进制,都把(60)个位置画出来了。我也准备好(floyd)最小环了。但是沙雕了,感觉每个位置都连边,复杂度太大emmmmmm。其实二进制对应位置(1)的个数大于(2),那么最小环就是(3),然后最多(120)个点(60)条边(可能不确切),然后(floyd)跑最小环即可。
    (floyd)求最小环:(d[i][j])(i)(j)不包含(k)点的最短距离。所以对于当前(k),我们已经求得(1{sim}k-1)(d[i][j]),然后枚举(1{sim}k-1)(d[i][j]),然后更新答案,(ans=min(ans,a[i][k]+a[k][j]+d[i][j])),表示包含(k)的环,其中(a)数组为最初距离。

    //#define DEBUG
    #include<bits/stdc++.h>
    using namespace std;
    const int N=100010;
    const int inf=0X3f3f3f3f;
    const long long INF = 0x3f3f3f3f3f3f3f3f;
    const double eps = 1e-6;
    const double pi = acos(-1.0);
    const int mod = 1000000007;
    typedef long long ll;
    
    int ans=60;
    ll b[N],a[150][150],d[150][150];
    int tot;
    
    int main() {
    	#ifdef DEBUG
    	freopen("in.txt","r",stdin);
    	#endif
        int n;
        scanf("%d",&n);
        ll x;
        for(int i=1;i<=n;i++) {
            scanf("%lld",&x);
            if(x) b[++tot]=x;
        }
        for(int i=0;i<=60;i++) {
            int cnt=0;
            for(int j=1;j<=tot;j++) {
                if(b[j]&(1ll<<i)) ++cnt;
            }
            if(cnt>=3) {puts("3");return 0;}
        }
        for(int i=1;i<=tot;i++) {
            for(int j=1;j<=tot;j++)
                if(i==j) d[i][j]=a[i][j]=0;
                else d[i][j]=a[i][j]=inf;
        }
        for(int i=1;i<=tot;i++) {
            for(int j=1;j<=tot;j++) {
                if(i==j) continue;
                if(b[i]&b[j]) a[i][j]=d[i][j]=1;
            }
        }
        //memcpy(d,a,sizeof(a));
        for(int k=1;k<=tot;k++) {
            for(int i=1;i<=k-1;i++) {
                for(int j=1;j<=k-1;j++)
                    if(i!=j&&a[i][k]+a[k][j]+d[i][j]<ans)
                        ans=a[i][k]+a[k][j]+d[i][j];
            }
            for(int i=1;i<=tot;i++) {
                for(int j=1;j<=tot;j++)
                    if(d[i][j]>d[i][k]+d[k][j])
                        d[i][j]=d[i][k]+d[k][j];
            }
        }
        if(ans==60) puts("-1");
        else printf("%d
    ",ans);
    }
    
  • 相关阅读:
    终于清楚了!!!【使用jenkins发布应用到tomcat详细过程】
    RocketMQ相关问题
    关于idea修改当前使用的git账户的问题
    Elasticsearchan安装初尝01-问题记录
    Redis学习日记-03
    Git初探笔记02
    Git初探笔记01
    Redis学习日记-02
    HDU 1017
    HDU 1013
  • 原文地址:https://www.cnblogs.com/ACMerszl/p/11396093.html
Copyright © 2020-2023  润新知