CF Educational68

  • A - Remove a Progression
#include 
 
int main(){
	int t , n , x ; 
	scanf ("%d",&t) ;
	while(t --){
		scanf ("%d%d",&n,&x) ;
		printf ("%d\n",2*x) ;
	}
	return 0 ; 
}
  • B.Yet Another Crosses Problem

题意:给一个图填充黑色,求填充最少的格子数使得有一个横跨图的十字架,
题解:一开始我是统计每行和每列的黑格子个数,求其最大值和最小值,若是行最大黑格子个数等于n且列最大黑格子个数等于m就存在一个横跨的十字架不需要补充黑色,然后要补充多少用(m+n-a-b)a,b为最大值,但是我发现了bug,就是下面这个两个图,如果按上面那条表达式求第二个图是没有问题的,关键是第一个图,因为行和列要填充的是同一个格子,所以如果按上面的表达式会多算一个格子。
改正:同样还是统计行和列的黑格子个数,然后图要存起来(这里数据太大不能用char二维数组,可以用vector数组存放),然后在后面遍历时,若当前格子为黑格子即‘*’时 ans = min(ans , m+n-row[i]-col[j]) , 若是当前格子为白格子即‘.’ ans = min(ans,m+n-row[i],col[j]) ;
CF Educational68_第1张图片
CF Educational68_第2张图片

#include 
#include 
#include 
using namespace std ; 
const int N = 5e4 + 5 ; 
int row[N] , col[N] ; 
vector<char> v[N] ; 
int main(){
	int t ;
	cin >> t ; 
	while(t --){
		int n , m ; 
		char ch ; 
		cin >> n >> m ; 
		memset(row,0,sizeof(row)) ;
		memset(col,0,sizeof(col)) ; 
		memset(v,0,sizeof(v)) ;
		for (int i = 0 ; i < n ; ++ i){
			for (int j = 0 ; j < m ; ++ j){
				cin >> ch ; 
				v[i].push_back(ch) ;
				if (ch == '*'){
					++ row[i] ; 
					++ col[j] ; 
				}
			}
		}
		int ans = 1e9 ; 
		for (int i = 0 ; i < n ; ++ i){
			for (int j = 0 ; j < m ; ++ j){
				if (v[i][j] == '*'){
					if (ans > m+n-row[i]-col[j])
						ans = m+n-row[i]-col[j] ;
				}
				else{
					if (ans > m+n-row[i]-col[j]-1)
						ans = m+n-row[i]-col[j]-1 ;
				}
			}
		}
		printf ("%d\n",ans) ; 
	}
	return 0 ; 
}

  • C - From S To T
    题意:给出三个字符串s , t , p ,从p中取出字符和s能否组成t
    题解:先处理字符串p,用一个数组记录字符串p中每个字符出现的次数,然后遍历字符串t,用两个变量i,j标记校对到哪里,若是p中的字符不够了则不能组成t,其他详细的见代码。
#include 
#include 
using namespace std ;
int alp[30] ; 
int main(){
	int t ; 
	cin >> t ;
	while(t --){
		string s , t , p ; 
		cin >> s ;
		cin >> t ;
		cin >> p ; 
		memset(alp,0,sizeof(alp)) ;
		for (int i = 0 ; i < p.length() ; ++ i)
			++ alp[p[i]-'a'] ;
		int j = 0 , tlen = t.length() ; 
		int i = 0 , slen = s.length() ; 
		bool flag = true ; 
		while(j < tlen){
			if (s[i] == t[j])	++i, ++ j ;
			else if (i >= slen || s[i] != t[j]){
				if (alp[t[j] - 'a'] <= 0)	{
					printf ("NO\n") ;
					flag = false ; 
					break ; 
				}
				else	{
					alp[t[j]-'a'] -- ;
					++ j ; 
				}
			}	
		}
		if (flag){
			if (i == slen && j == tlen) 
				printf ("YES\n") ; 
			else 
				printf ("NO\n") ;
		}
	
	}
	return 0 ; 
}

D. 1-2-K Game(博弈)
题意:给出n个格子和k,可以走1步或者2步或者k步,谁先走到0谁赢,Alice先手,打印出赢的人的名字。
题解:根据题意可知1 2 k 为必赢点,然后推一下规律
比较详细的题解:题解
博弈论:https://www.cnblogs.com/DWVictor/p/10237506.html

#include 
int main(){
	int t ;
	scanf ("%d",&t) ; 
	while(t--){
		int n , k ; 
		scanf ("%d%d",&n,&k) ;
		if (k % 3 == 0){
			n %= k+1 ; 
			if (n == k)
				printf ("Alice\n") ;
			else{
				if (n % 3 == 0)		printf ("Bob\n") ;
				else	printf ("Alice\n") ;
			}
			continue ; 
		}
		if (n % 3 == 0)
			printf ("Bob\n") ;
		else
			printf ("Alice\n") ;  
	}
	return 0 ; 
}

你可能感兴趣的:(CF)