• codeforces #275 div2题解


    A题大意:

         给你l,r,问你在l~r之间,是否存在 a和b互质 , b和c互质 ,但是 a,c不互质 的情况;其中l<=a<b<c<=r;如果存在,就输出a,b,c;不存在就输出-1;

        其中(1 ≤ l ≤ r ≤ 1018; r - l ≤ 50).

       

    - -r-l<=50,这么水我也是醉了,开个longlong , 枚举他们是否满足以上要求即可,顺便复习了一下辗转相除;

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    long long l,r;
    int gcd(long long a,long long b){
    	if(b==0) return a;
    	else return gcd(b,a%b);
    }
    int main(){
    	cin>>l>>r;
    	for(long long i=l;i<=r;i++)
    	   for(long long j=i+1;j<=r;j++)
    	       for(long long k=j+1;k<=r;k++){
    	       	  if(i!=j && i!=k && j!=k){
    	       	  	  if(gcd(j,i)==1 && gcd(k,j)==1 && gcd(k,i)!=1){
    	       	  	  	 cout<<i<<" "<<j<<" "<<k;
    	       	  	  	 return 0;
    	       	  	  }
    	       	  }
    	       }
    	cout<<"-1";
    	return 0;
    } 
    

     

    B题大意:

    你给第一个朋友cnt1个数,给第二个朋友cnt2个数,在给第一个朋友的数不可以被x整除,给第二个朋友的数不可以被y整除,如果某个数既不能被x整除也不能被y整除,那么它不能同时出现在两个朋友的数里

    然后你得在1.2.3.....n中选出符合要求的cn1个数和cnt2个数,问你最小的n为多少?

    感觉这套的B题好坑啊- -(其实是自己弱....)

    刚开始以为枚举就好了,B题嘛反正,然后还是超时了;之后觉得那就优化一下暴力好了- -结果还是不行;

    后面想到利用余数,例如 x个数里,可以有x-1不被x整除的数之类的,但是处理出来的答案还是会有偏差

    然后实在没有办法了!就看了别人的代码!- - 妈蛋...自己都想到用余数了都,还不知道要二分答案!我个傻逼....

    以上是我的傻逼的思考过程,- -说说这一题的正确思路,就是常规的二分答案;

    如果验证是否可行呢?(方法有很多,这里说一下我的思路)

    pp为二分的那个数:

     __int64 qq =  (pp - pp/x - pp/y + pp/(x*y));//符合要求的cnt1+cnt2,注意这里是+pp/(x*y),因为除以x和除以y,所以扣掉的个数有重复的地方;
    int cont1 = max(0, (int)(a-(pp/y-pp/(x*y))));//
    int cont2 = max(0, (int)(b-(pp/x-pp/(x*y)))); if(qq >= cont1+cont2) return 1; return 0;

     附上代码:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int a, b, x, y;
    int judge(long long pp){
        __int64 qq =  (pp - pp/x - pp/y + pp/(x*y));
        int cont1 = max(0, (int)(a-(pp/y-pp/(x*y))));
        int cont2 = max(0, (int)(b-(pp/x-pp/(x*y))));
        if(qq >= cont1+cont2)
            return 1;
        return 0;
    
    }
    long long solve(long long l, long long r){
        __int64 res;
        while(l <= r){
            __int64 mid = (l+r) / 2;
            if(judge(mid)){
                res = mid;
                r = mid - 1;
            }
            else
                l = mid + 1;
        }
        return res;
    }
    int main(){
        while(scanf("%d%d%d%d", &a, &b, &x, &y) == 4){
            long long ans = solve(1, (a+b)*2+1);
            printf("%I64d
    ", ans);
        }
        return 0;
    }
    

      

    C题大意:

    给你一个数列1.2.3...n,让你交换这个数列中的数,使得相邻两个数相减得出的数有k个是不同的,让你输出你交换后满足题意的数列;

    - -感觉是见过最傻逼的C题,大概就是贪心的思想吧。

    你从头尾开始枚举,交换枚举的之后,他们的差值肯定都不相同。之后乱搞一下就可以了,你可以交换枚举k-2次,然后按顺序输出;反正方法很多,乱搞搞就过了;

    附上代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    int main(){
    	int n,k,j=1;
    	cin>>n>>k;
    	int temp1=1,temp2=n;
    	for(int i=1;i<=n;i++){
    		if(j%2){
    			cout<<temp1<<" ";temp1++;
    		}
    		else {
    			cout<<temp2<<" ";temp2--;
    		}
    		if(j!=k) j++;
    	}
    	return 0;
    }
    

     

    D题线段树...不会,只剩几天了,觉得没有学习的必要

  • 相关阅读:
    android sdk里的各目录作用
    android广播接收器
    Android 服务
    全球10个智慧城市应用案例
    大数据应用蓝皮书:未来涉及5个热点领域
    2018杭州-云栖大会
    上海世界人工智能大会大佬观点
    2018世界人工智能大会
    大数据安全
    2018第37周六
  • 原文地址:https://www.cnblogs.com/polebug/p/4055587.html
Copyright © 2020-2023  润新知