首先发三个题目,其链接如下:
http://hihocoder.com/contest/mstest2015dec3/problems
解析:
第一个题目是暴力,简单的枚举就可以解决,代码如下所示:
#include <stdlib.h> #include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; char Map[300][300]; int Row, Col; char Sen[3][3]; vector<pair<int, int> > result; bool Handle(); bool Check(int i, int j); void Rotate(); int main(){ while(Handle()){ //empty while } } bool CMP(const pair<int, int>& lhs, const pair<int, int>& rhs); bool Handle(){ if(!(cin>>Row>>Col)){ return false; } result.clear(); for(int i= 0; i< Row; ++i){ for(int j= 0; j< Col; ++j){ cin>>Map[i][j]; } } for(int i= 0; i< 3; ++i){ for(int j= 0; j< 3; ++j){ cin>>Sen[i][j]; } } for(int l= 0; l< 4; ++l){ for(int i= 1; i< Row-1; ++i){ for(int j= 1; j< Col-1; ++j){ if(Check(i,j)){ result.push_back(make_pair(i+1,j+1)); } } } Rotate(); } sort(result.begin(),result.end()); result.erase(unique(result.begin(),result.end()),result.end()); for(int i= 0; i< result.size(); ++i){ cout<<result[i].first<<' '<<result[i].second<<endl; } return true; } bool Check(int i, int j){ for(int x= 0; x< 3; ++x){ for(int y= 0; y< 3; ++y){ if(Sen[x][y]!= Map[i-1+x][j-1+y]) return false; } } return true; } void Rotate(){ for(int i= 0; i< 3; ++i){ for(int j= 0; j<= i; ++j){ swap(Sen[i][j],Sen[j][i]); } } for(int i= 0; i< 3; ++i){ swap(Sen[0][i],Sen[2][i]); } } bool CMP(const pair<int, int>& lhs, const pair<int, int>& rhs){ if(lhs.first!= rhs.first){ return lhs.first< rhs.first; } return lhs.second< rhs.second; }
#include <iostream> using namespace std; typedef long long lld; int N, K; lld GS[100001]; bool Handle(); int main(){ while(Handle()){ //empty while } } bool Check(int m);//返回true,Ho赢,否则,Hi赢 bool Handle(){ if(!(cin>>N>>K)) return false; for(int i= 0; i< N; ++i){ cin>>GS[i]; } int l= 1, r= K+1, m; while(l<= r){ m= (l+r)>>1; if(!Check(m)){ l= m+1; }else{ r= m-1; } } while(Check(l))--l; cout<<l+1<<endl; return true; } inline lld MIN(lld x, lld y){ return x< y ? x:y; } bool Check(int m){//返回true,Ho赢,否则,Hi赢 lld Left= 0; int X= 0; for(int i= 0; i< N; ++i){ Left+= m; if(GS[i]<Left){ ++X; } Left-=min(Left, GS[i]); } if(N&1){ return X>=(N+1)>>1; }else{ return X>(N>>1); } }
第三个是动态规划,比较简单,代码如下所示:
#include <iostream> #include <stdlib.h> #include <string.h> using namespace std; int dp[101][101][51]; bool Visit[101][101][51]; int GCD[101][101]; int M, N; const int MOD= 1000000007; bool Handle(); int gcd(int x, int y); int main(){ for(int i= 1; i< 101; ++i){ for(int j= 1; j<=i; ++j){ GCD[i][j]=GCD[j][i]= gcd(j,i); } } while(Handle()){ //empty while } } int Fetch(int i, int j, int k); bool Handle(){ if(!(cin>>M>>N)) return false; memset(Visit,0,sizeof(Visit)); memset(dp,0,sizeof(dp)); int Sum= 0; cout<<Fetch(M,M,N)<<endl; return true; } int gcd(int x, int y){ return !x ? y:gcd(y%x,x); } int Fetch(int i, int j, int k){ if(Visit[i][j][k]){//have got return dp[i][j][k]; } Visit[i][j][k]= true; if(j==1){ dp[i][j][k]= (k==1)&&(i<=1); return dp[i][j][k]; }else{ dp[i][j][k]= 0; dp[i][j][k]+= Fetch(i,j-1,k); if(i>= j) dp[i][j][k]+= Fetch(i-j,j-1,k/GCD[j][k]); dp[i][j][k]%=MOD; return dp[i][j][k]; } }