首先发三个题目,其链接如下:
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];
}
}