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; }