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代码

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

posted @ 2020-04-04 23:01  dsrcis  阅读(124)  评论(0编辑  收藏  举报