• Codeforces Round #630 (Div. 2)



    题外话

    其实这场我没打(太困了),咕咕咕了好久才写了四个题QAQ

    A

    A题意

        问你是否通过题面上给的四个移动方式(全部使用完)使得从一开始的位置移动没有出界
    

    A思路

        其实就是判断上下,左右之间的差,和界限的距离, 注意要关注一下想x1 ==x2 和y1 ==y2 的这两种情况
    

    A代码

    #include <bits/stdc++.h>
    #include <ext/pb_ds/assoc_container.hpp>
    #include <ext/pb_ds/tree_policy.hpp>
    #define iinf 0x3f3f3f3f
    #define linf (1ll<<60)
    #define eps 1e-8
    #define maxn 1000010
    #define maxe 1000010
    #define cl(x) memset(x,0,sizeof(x))
    #define rep(i,a,b) for(i=a;i<=b;i++)
    #define drep(i,a,b) for(i=a;i>=b;i--)
    #define em(x) emplace(x)
    #define emb(x) emplace_back(x)
    #define emf(x) emplace_front(x)
    #define fi first
    #define se second
    #define pb push_back
    #define de(x) cerr<<#x<<" = "<<x<<endl
    #define __i __int128
    using namespace std;
    using namespace __gnu_pbds;
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> pll; 
    
    ll read(ll x=0)
    {
        ll c, f(1);
        for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
        for(;isdigit(c);c=getchar())x=x*10+c-0x30;
        return f*x;
    }
    const int N =100010;
    int n , k, m ;
    ll mod = 1e9+7;
    ll ar[100010];
    int h[N] , ne[2*N] , idx, e[2*N];
    int dep[N], f[1010][1010];
    
    int main()
    {
    	    ios::sync_with_stdio(0);
        cin.tie(0), cout.tie(0);
      	cin >>n;
      	while (n--){
      		int a ,b,c,d;
      		cin >>a>>b>>c>>d;
      		int x,y,x1,y1,x2,y2;cin >>x>> y >>x1>>y1>>x2>>y2 ;
      		int u, l;u = a-b;l = c-d ;
      		if(x1 ==x2){
      			if(a==b&&b!=0){
      				cout<<"No"<<endl;
      				continue;
    			  }
    		  }
    		if(y1 ==y2){
    			if(c==d && c!=0){
    				cout<<"No"<<endl;
    				continue ;
    			}
    		}
      		if(u<0){
      			if(x-u>max(x1,x2)){
    			  cout<<"NO"<<endl;
    			  continue ;
    			  }
    		  }
    		else if(u>=0){
    			if(x-u<min(x1,x2)){
    				cout<<"NO"<<endl;
    			  continue ;
    			}
    		}
    		if(l < 0){
    			if(y-l>max(y1,y2)){
    				cout<<"NO"<<endl;
    			  continue ;
    			}
    		}
    		else if(l>=0){
    			if(y-l<min(y1,y2)){
    				cout<<"NO"<<endl;
    			  continue ;
    			}
    		}
    		cout<<"YES"<<endl;
    	  }
        return 0;
    }
    

    B

    B题意

    给你一堆数, 让你通过GCD的性质(一组中的所有数,与其他数gcd都大于1的可以是一个颜色) ,分出需要多少颜色(不需要搞出最多和最少 )

    B思路

    先看数据范围哈哈!1000, 然后发现这个题和质因数有很大的关系,
    - 因为数据范围是1000, 所以一共在1000里面有11个质数,且最大的是31
    - 通过唯一分解定理, 可知道所有数都可以分为质因数
    - 因为质因数一共就只有11个,符合题面上的最大m《=11 的条件, 所以只需要让每个数的最小质因数相同的为一组就行(最大啥的都可以)

    B代码

    #include <bits/stdc++.h>
    #include <ext/pb_ds/assoc_container.hpp>
    #include <ext/pb_ds/tree_policy.hpp>
    #define iinf 0x3f3f3f3f
    #define linf (1ll<<60)
    #define eps 1e-8
    #define maxn 1000010
    #define maxe 1000010
    #define cl(x) memset(x,0,sizeof(x))
    #define rep(i,a,b) for(i=a;i<=b;i++)
    #define drep(i,a,b) for(i=a;i>=b;i--)
    #define em(x) emplace(x)
    #define emb(x) emplace_back(x)
    #define emf(x) emplace_front(x)
    #define fi first
    #define se second
    #define pb push_back
    #define de(x) cerr<<#x<<" = "<<x<<endl
    #define __i __int128
    using namespace std;
    using namespace __gnu_pbds;
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> pll;
    
    ll read(ll x=0)
    {
        ll c, f(1);
        for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
        for(;isdigit(c);c=getchar())x=x*10+c-0x30;
        return f*x;
    }
    const int N =100010;
    int n , k  =1, m ;
    int ar[10010];
    
    int cr[10010];
    void clear(unsigned char *pta, int size )
    {
        while(size>0)
        {
            *pta++ = 0;
            size --;
        }
    }
    int main()
    {
    	    ios::sync_with_stdio(0);
        cin.tie(0), cout.tie(0);
        cin >>n;
        while(n--){
            cin >>m;
            k =1 ;pii br[1010];
            for(int i =0 ;i<m;i++)cin >> ar[i];
            for(int i=0;i<m;i++){
                for(int j=2;j<=ar[i]/j;j++){
                    if(ar[i]%j==0){
                          //  cout<<j<<endl;
                        if(br[j].first == 0){
                            cr[i] = k;
                            br[j].second = k;
    //                        cout<<br[j].second << " "<<j <<endl;
                            k++;
                        }
                        else if(br[j].first >0)cr[i] = br[j].second;
                        br[j].first ++ ;
                        break;
                    }
                }
    
            }
            int cnt =0 ;
            for(int i=2;i<=31;i++){
                if(br[i].first!=0)cnt ++ ;
    
            }
            cout<<cnt <<endl;
            for(int i=0;i<m;i++)cout<<cr[i]<<" ";
            cout<<endl;
        }
    
        return 0;
    }
    

    C

    C题意

    • S 自身是要回文的
    • 每k组也是要回文
    • m可以整除k
      问你最少需要修改多少字符符合上述条件

    C思路

    • 直觉一想,肯定是每个有关系的字符中, 把剩余和最多字符不相同的字符修改成最多的那个字符
    • 然后因为每k组要回文,所以先判断一下k的奇偶性质
    • 然后通过画图, 其实你可以 得到这个关系$ i +jk == jk+k-i-1 $ 其中,j是k的第几组
    • 剩下的就是通过相加和相减求出最少的修改次数即可

    C代码

    #include <bits/stdc++.h>
    #include <ext/pb_ds/assoc_container.hpp>
    #include <ext/pb_ds/tree_policy.hpp>
    #define iinf 0x3f3f3f3f
    #define linf (1ll<<60)
    #define eps 1e-8
    #define maxn 1000010
    #define maxe 1000010
    #define cl(x) memset(x,0,sizeof(x))
    #define rep(i,a,b) for(i=a;i<=b;i++)
    #define drep(i,a,b) for(i=a;i>=b;i--)
    #define em(x) emplace(x)
    #define emb(x) emplace_back(x)
    #define emf(x) emplace_front(x)
    #define fi first
    #define se second
    #define pb push_back
    #define de(x) cerr<<#x<<" = "<<x<<endl
    #define __i __int128
    using namespace std;
    using namespace __gnu_pbds;
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> pll; 
    
    ll read(ll x=0)
    {
        ll c, f(1);
        for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
        for(;isdigit(c);c=getchar())x=x*10+c-0x30;
        return f*x;
    }
    const int N =100010;
    int n , k, m ;
    ll mod = 1e9+7;
    ll ar[100010];
    int h[N] , ne[2*N] , idx, e[2*N];
    int dep[N], f[1010][1010];
    
    int main()
    {
    	    ios::sync_with_stdio(0);
        cin.tie(0), cout.tie(0);
        cin >>n;
    	while(n--) {
    		cin >>m>>k ;string s; 
    		cin >>s;
    		ll sum =0;
    		
    		
    		for(int i=0;i<((k&1) ? (k+1)/2: k/2);i++){
    			int cnt=0;map<char , int > mp;
    			for(int j=0;j<m/k;j++){
    				if((k&1) && i ==(k+1>>1) -1)mp[s[i+j*k]]++;
    				else if(s[i+j*k] == s[j*k+k-i-1 ])mp[s[i+j*k]]+=2;
    				else mp[s[i+j*k]]++ ,mp[s[j*k+k-i - 1 ]]++;
    				cnt= max(mp[s[i+j*k]],max( mp[s[j*k+k-i-1]], cnt));
    			}//cout<<cnt[i]<<" "<< i <<  endl;
    		//	cout<<cnt<<endl; 
    			if(k&1){
    				if(i == (k+1)/2-1)sum +=m/k-cnt;
    				else sum +=2*m/k-cnt;
    			//	cout<<sum<<endl;
    			}
    			else  sum +=2*m/k-cnt;
    	}
    		cout<<sum<<endl;
    	}
        return 0;
    }
    

    D

    D题意

    • 假设有一个数字矩阵,每次可以向下或向右,问从左上角走到右下角的数字和最多是多少,那么显然这是一个dp。
    • 现在不问你数字和,而是把路径上的所有数都&起来,如果还是dp显然是错的。假设dp的到的结果是x,正确答案是y。
    • 现在给定k,需要你构造一个矩阵,使得|y-x|=k
      懒得自己写了(搬运)原题解传送门

    D思路

    还是上面的大佬的,这个大佬的想法真的很棒

    D代码

    还是上面大佬的思路下的代码,我就不献丑了

  • 相关阅读:
    Sql例子Sp_ExecuteSql 带参数
    Flex显示麦克风当前音量
    无法将 flash.display::Sprite@156b7b1 转换为 mx.core.IUIComponent
    FMS (端口问题)如何穿透防火墙
    19:A*B问题
    6264:走出迷宫
    2753:走迷宫
    1792:迷宫
    换钱问题(经典枚举样例)
    1943(2.1)
  • 原文地址:https://www.cnblogs.com/gaohaoy/p/12634997.html
Copyright © 2020-2023  润新知