A. Flipping Game
就A了AB题
第一眼看到这题,就想到直接暴搜,但很怕会超时,所以没敢做,然后一直再推,看有什么规律,后面发现很难找,见别人暴搜过了,我才敢写唉~WA了好多次
代码:
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <stdlib.h>
#include <queue>
using namespace std;
int a[105];
int main()
{
int n,i,j,sum=0,s,k,mmax=0;
scanf("%d",&n);
for(i=1; i<=n; i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
for(i=1; i<=n; i++)
{
for(j=i; j<=n; j++)
{
s = sum;
for(k=i; k<=j; k++)
{
s -= a[k];
s += (1-a[k]);
if(s>mmax) mmax = s;
}
}
}
printf("%d\n",mmax);
return 0;
}
B. Hungry Sequence
直接筛选素数输出
代码:
#include <iostream>//B
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <stdlib.h>
#include <queue>
using namespace std;
const int M=10000001;
int p[M];
int s[M];
int main()
{
int n,i,j,l=0;
p[1]=1;
for(i=2;i<=M;i++)
{
if(!p[i])
{
s[l++]=i;
for(j=2*i;j<=M;j+=i)
{
p[j]=1;
}
}
}
cin>>n;
for(i=0;i<n-1;i++)
{
printf("%d ",s[i]);
}
printf("%d",s[n-1]);
return 0;
}
C. Magic Five
仔细推就可以推出一个公式(2^(k*l)/(2^l-1)*sum, sum=sum+2^i(i为0或5的位置),其实就是一个等比数列的求和,但是数据量很大,必须用快速取幂的方法,另外对等比数列,仔细观察,发现
T[n]=T[n/2]+T[n/2]*2^(n/2)......当n%2==0时
T[n]=T[n/2]+T[n/2]*2^(n/2)+2^n......当n%2==1时
代码:
#include <iostream>//C
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <stdlib.h>
#include <queue>
using namespace std;
const int M=100001;
const long long C=1e9+7;
char s[M];
long long sum,q;
int l;
int powmode(int a,__int64 b)//快速幂取余
{
if(b==0)return 1;
if(b==1)return a;
__int64 tmp=powmode(a,b/2)%C;
tmp=tmp*tmp%C;
if(b%2==1)tmp=tmp*a%C;
return (int)tmp;
}
int fun(long long n)
{
if(n==1)return sum;
__int64 tmp=fun(n/2);
tmp=(tmp+tmp*powmode(q,n/2))%C;
if(n%2)tmp=(tmp+powmode(2,(n-1)*l)*sum%C)%C;
return (int)tmp;
}
int main()
{
int k,i;
int ans;
while(scanf("%s %d",s,&k)!=EOF)
{
l=strlen(s);
ans=sum=0;
q=powmode(2,l)%C;
for(i=0; i<l; i++)
{
if(s[i]=='0' || s[i]=='5')
{
sum=(sum+powmode(2,i))%C;
}
}
ans=fun(k);
cout<<ans<<endl;
}
return 0;
}
D. Block Towe
r
给出n*m的格子,可以在空地上建房子,蓝色的房子可以住100个人,红色的房子可以住200个人,如何建房子使得能够住的人最多,并且要求红房子必须建在蓝色房子旁边,即有公共边。
画一个格子分析一下,发现只要用DFS搜索,搜到不能再走时那个点必须是红色的,也就是思路是,和周边公共边最多的那个格子最好是建蓝色房子,那么它的周边就可以全部建红色了(只要是空地)。
刚开始没有想到这个,想着只要找到一个空地,然后遍历它的周围,只要还有空地的,就在它这里建红房子,但是得出来不是最优,人数不是最大的。
代码:
#include <iostream>//D
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <stdlib.h>
#include <queue>
using namespace std;
const int M=100001;
struct node
{
int x,y;
char cr;
} a[5000005];
int n,m;
int dis[4][2]= {{1,0},{0,-1},{-1,0},{0,1}};
int vis[505][505];
char g[505][505];
int num;
int l;
bool inside(int x,int y)
{
if(x<1 || x>n || y<1 || y>m)
return false;
return true;
}
void dfs(int x,int y)
{
int i;
num++;
vis[x][y]=1;
for( i=0; i<4; i++)
{
int fx=x+dis[i][0];
int fy=y+dis[i][1];
if(inside(fx,fy) && g[fx][fy]=='.' && vis[fx][fy]==0)
dfs(fx,fy);//一直没法往下找时退回,那个点应置为红色
}
if(num>1)
{
a[l].x=x;
a[l].y=y;
a[l].cr='D';
l++;
a[l].x=x;
a[l].y=y;
a[l].cr='R';
l++;
g[x][y]='R';
}
num--;
}
int main()
{
memset(vis,0,sizeof(vis));
int i,j;
char data;
scanf("%d%d",&n,&m);
l=0;
for(i=1; i<=n; i++)
{
for(j=1; j<=m; j++)
{
cin>>data;
g[i][j]=data;
if(g[i][j]=='.')
{
a[l].cr='B';
a[l].x=i;
a[l].y=j;
l++;
}
}
}
for(i=1; i<=n; i++)
{
for(j=1; j<=m; j++)
{
if(vis[i][j]==0 && g[i][j]=='.')
{
num=0;
dfs(i,j);
}
}
}
cout<<l<<endl;
for(i=0; i<l; i++)
printf("%c %d %d\n",a[i].cr,a[i].x,a[i].y);
return 0;
}