Codeforces Round#258 div2 A B C (Problemset 451)

A. Game With Sticks

        题意:n根水平,m根垂直棍子摆成网格状,两个人轮流拿,每次选一个交点,拿掉相关棍子,没有交点可拿的输。

        思路:每次肯定拿掉一水平一垂直,直接看min(n,m)%2判断。

#include <iostream>  
#include <stdio.h>  
#include <cmath>  
#include <algorithm>  
#include <iomanip>  
#include <cstdlib>  
#include <string>  
#include <memory.h>  
#include <vector>  
#include <queue>  
#include <stack>  
#include <ctype.h>  
#define INF 1000000

using namespace std;


int n,m;
int main(){
	
	
	while(cin>>n>>m){
		int _min=min(n,m);
		if(_min%2){
			cout<<"Akshat"<<endl;
		}else{
			cout<<"Malvika"<<endl;
		}
	}
	return 0;
}


B. Sort the Array


        题意:给一个整形数组,每个元素不一样。问是否可以反转其中一段,使其递增。

        思路:可以把数组分为若干区间,每个区间上是单调递增或递减的,发现单调性改变时做标记。有可能满足题意的情况有:增、增减(反转减的那段)、增减增(反转减)、减(全部反转)、减增(反转减)。符合这些情况的数组,再比较一下端点数值的大小就可以了。


#include <iostream>  
#include <stdio.h>  
#include <cmath>  
#include <algorithm>  
#include <iomanip>  
#include <cstdlib>  
#include <string>  
#include <memory.h>  
#include <vector>  
#include <queue>  
#include <stack>  
#include <ctype.h>  
#define INF 1000000

using namespace std;

int num[100010];
int key[100010];

int n,m;
int main(){
	
	
	while(cin>>n){
		bool da;
		bool b;
		int cnt=0;
		for(int i=1;i<=n;i++){
			scanf("%d",&num[i]);
			
			if(i==1){
				continue;
			}else if(i==2){
				if(num[i]>num[i-1]){
					da=true;
					b=true;
				}else{
					da=false;
					b=false;
				}
			}else{
				if(num[i]>num[i-1]){
					if(!da){
						cnt++;
						key[cnt]=i;
					}
					da=true;
				}else{
					if(da){
						cnt++;
						key[cnt]=i;
					}
					da=false;
				}
			}
		}
		if(b&&cnt>2||(!b&&cnt>1)){
			cout<<"no"<<endl;
			continue;
		}
		if(b){//
			if(cnt==0){
				cout<<"yes"<<endl;
				cout<<"1 1"<<endl;
			}else if(cnt==1){
				if(num[n]>num[key[1]-2]){
					cout<<"yes"<<endl;
					cout<<key[1]-1<<" "<<n<<endl;
				}else{
					cout<<"no"<<endl;
				}
			}else{
				if(num[key[2]-1]>num[key[1]-2]&&num[key[1]-1]<num[key[2]]){
					cout<<"yes"<<endl;
					cout<<key[1]-1<<" "<<key[2]-1<<endl;
				}else{
					cout<<"no"<<endl;
				}
			}
		}else{
			if(cnt==0){
				cout<<"yes"<<endl;
				cout<<"1 "<<n<<endl;
			}else{
				if(num[1]<num[key[1]]){
					cout<<"yes"<<endl;
					cout<<"1 "<<key[1]-1<<endl;
				}else{
					cout<<"no"<<endl;
				}
			}
		}
	}
	return 0;
}


C. Predict Outcome of the Game

        题意:足球比赛,三个队伍,共n场,已经比了k场,你全错过了。但是你知道队伍1和队伍2胜场差的绝对值d1,队伍2和队伍3胜场差的绝对值d2,问n场全部比完以后,三队胜场是否可以相同。

        思路:d1,d2是绝对值,无法直接得知谁赢的多。其实也就4种可能 (1比2多,2比3多)(1比2多,2比3少)(1比2少,2比3多)(1比2少,2比3少)。然后逐一检验已进行比赛的合理性(比如可以像解方程一样算每队胜场,看是否有解),和未进行比赛是否存在打平可能(让胜少的队伍获胜,直到胜场一样,然后剩余比赛场数又是3的倍数)就行了。注意只要存在一种可能,就是有解。n的范围比较大,需要long long。

#include <iostream>  
#include <stdio.h>  
#include <cmath>  
#include <algorithm>  
#include <iomanip>  
#include <cstdlib>  
#include <string>  
#include <memory.h>  
#include <vector>  
#include <queue>  
#include <stack>  
#include <ctype.h>  
#define INF 1000000

using namespace std;


long long t;
int main(){
	long long n,k,d1,d2;
	cin>>t;
	while(t--){
		scanf("%I64d%I64d%I64d%I64d",&n,&k,&d1,&d2);
		long long r=n-k;
		bool flag=false;
		long long tmp;
		
		tmp=r-d1-d1-d2;
		if(tmp>=0&&!(tmp%3)){
			long long test=k-d2-d2-d1;
			if(test>=0&&!(test%3) )flag=true;
		}
		
		
		tmp=r-max(d1,d2)-abs(d1-d2);
		if(tmp>=0&&!(tmp%3)){
			long long test=k-d1-d2;
			if(test>=0&&!(test%3) )flag=true;
		}
		
		
		
		tmp=r-d1-d2;
		if(tmp>=0&&!(tmp%3)){
			long long test=k-max(d1,d2)-abs(d1-d2);
			if(test>=0&&!(test%3) )flag=true;
		}
		
		tmp=r-d1-d2-d2;
		if(tmp>=0&&!(tmp%3)){
			long long test=k-d1-d1-d2;
			if(test>=0&&!(test%3) )flag=true;
		}
		
		
		
		if(flag){
			cout<<"yes";
		}else{
			cout<<"no";
		}
		cout<<endl;
	}
	return 0;
}








你可能感兴趣的:(codeforces,codeforces,round258)