Codeforces Round #648 (Div. 2)

链接 : https://codeforces.com/contest/1365/problems

problem A

统计可用的行和列的最小值, 模2输出即可

/*
 * Author: RoccoShi
 * Time: 2020-06-07 22:35:02
*/

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

int vix[50];
int viy[50];
int cntx=0, cnty=0;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t; 
    cin >> t;
    while(t--){
    	int m, n;
    	cin >> n >> m;
    	int x;
    	for(int i = 0; i < n; ++ i)
    		for(int j = 0; j < m; ++ j){
    			cin>>x;
    			if(x==1){
    				vix[i] = 1;
    				viy[j] = 1;
    			}
    		}
    	for(int i = 0; i < n; ++ i)
    	{
    		if(vix[i]==0) cntx++;
    	}	
    	for(int i = 0; i < m; ++ i){
    		if(viy[i]==0) cnty++;
    	}
    	int ans = min(cntx,cnty) % 2;
    	if(ans==1)cout << "Ashish" <<endl;
    	else cout << "Vivek" <<endl;
    	memset(vix,0,sizeof(vix));
    	memset(viy,0,sizeof(viy));
   		cntx=0;cnty=0;
    }
    
    return 0;
}

problem B

可以知道, 只要有0,1那么这个数组想换成啥样就换成啥样

如果全0 or 全1, 数组必须得是非递减

/*
 * Author: RoccoShi
 * Time: 2020-06-07 22:35:02
*/

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while(t--){
    	int n,a,b,tmp;
    	cin>>n;
    	int flag = 0;
    	for(int i=0;i<n;++i){
    		cin >> a;
    		if(i!=0)
    			if(a<tmp)
    				flag = 1;
    		tmp = a;
    	}
    	for(int i=0;i<n;++i){
    		cin >> b;
    		if(i!=0)
    			if(b!=tmp)
    				flag = 0;
    		tmp = b;
    	}
    	if(flag == 0)cout<<"Yes"<<endl;
    	else cout<<"No"<<endl;
    }
    return 0;

}

problem C

固定其中一个数组不动, 另一个数组最多右移n-1次

用一个数组vis保存数组a的每个值的位置

vis[i]表示 : i在数组a中的位置为vis[i]

当输入数组b时, 直接用ans = vis[b[i]] - i ( 这个数在a的位置 - 这个数在b的位置 )

如果>=0, 则此数移动ans次可匹配

如果<0, 则此数移动n+ans次可匹配

用一个map装移动x次能匹配的数的个数, 最后遍历取最大值为答案

/*
 * Author: RoccoShi
 * Time: 2020-06-07 22:35:02
*/

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N = 4e5 + 5;
int a[N], b[N], vis[N];
int ans = 0;
map<int,int> mp;


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
	cin >> n;
	for(int i = 0; i < n; ++i){
		cin >> a[i];
		vis[a[i]] = i;
	}
	for(int i = 0; i < n; ++i){
		cin >> b[i];
		ans = vis[b[i]] - i;
		if(ans >= 0)
			mp[ans]++;
		else
			mp[n+ans]++;
	}
	map<int,int>::iterator it;
	ans = -1;
	for(it = mp.begin(); it != mp.end(); ++it)
	{
		ans = max(ans, it->second);
	}
	cout << ans << endl;
	return 0;
}

problem D

统计好人个数, 然后把坏人全封死, 再从终点往回dfs统计好人的个数, 如果好人全找到了, 就YES否则NO

/*
 * Author: RoccoShi
 * Time: 2020-06-07 22:35:02
*/

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
char a[55][55];
int vis[55][55];
int m, n, ans;

int dfs(int x,int y){
	if(vis[x][y] || a[x][y]=='#')
        return 0;
    int ans = 0;
    vis[x][y] = 1;
    if(a[x][y] == 'G')
    {
        ans++;
    }
    ans = ans + dfs(x+1,y);
    ans = ans + dfs(x-1,y);
    ans = ans + dfs(x,y+1);
    ans = ans + dfs(x,y-1);
    return ans;
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while(t--){
    	cin >> m >> n;
    	for(int i=0;i<=m+1;++i)
    	{
    		a[i][0] = '#';
    		a[i][n+1] = '#';
    	}
    	for(int j=0;j<=n+1;++j)
    	{
    		a[0][j] = '#';
    		a[m+1][j] = '#';
    	}
        int cntG=0;
    	for(int i = 1; i <= m; ++i){
    		for(int j = 1; j <= n; ++j)
    		{
    			cin>>a[i][j];
                if(a[i][j] == 'G') cntG++;
    		}	
    	}
    	for(int i = 1; i <= m; ++i){
    		for(int j = 1; j <= n; ++j)
    		{
    			if(a[i][j]=='B'){
    				a[i][j-1]!='B'?a[i][j-1]='#':1;
    				a[i][j+1]!='B'?a[i][j+1]='#':1;
    				a[i+1][j]!='B'?a[i+1][j]='#':1;
    				a[i-1][j]!='B'?a[i-1][j]='#':1;
    			}
    		}	
    	}

    	ans = dfs(m,n);
    	if(ans == cntG)cout<<"Yes"<<endl;
    	else cout<<"No"<<endl;
    	memset(vis,0,sizeof(vis));
    }
    return 0;
}

这次比赛只写了前2题, 后两题补的
如果说学到了什么, 那就是找通解不要瞎jier特判, 判到最后一堆bug还把人给判晕了