A题:Flipping Game
题意:n个数字由0,1组成,一次反转定义为将连续的n个0翻转为1.求经过一次翻转后,1的个数做多是多少???
很水的一道题,方法就是求出1的个数和连续0个数最多的区间长度。二者相加就是答案~~~
#include
#include
using namespace std;
int main()
{
int i,n,a,x,y,mx;
cin >> n;
mx=0,x=0,y=0;
for(i=0;i> a;
if(a) y++;
if(!a)
{
x++;
if(x>mx)
mx=x;
}
else if(x>0) x--;
}
if(!mx) mx--;
cout << y + mx << endl;
return 0;
}
B题:Hungry Sequence
这道题,要求不是很严格~~只要输出那个数,其中任意两个数不能整除就可以,那么n—2*n-1之间的连续n个数任意两个都不能整除,输出即可
#include
using namespace std;
int main()
{
int n,i;
cin>>n;
for(i=n; i<2*n; ++i)
cout << i << " ";
return 0;
}
C题:Magic Five
题意:有一个字符串,可以在这个串中去掉0个或者多个(不能全部)字符使能够被5整除。求共有多少种方式?
输入:一个字符串s和整数k,表示k个s相连接。
输出:有多少种方式是字符串表示的数能够被5整除。
解题方法:根据快速幂和费马小定理求解。否则会TLE。
思路:设max=1000000007先求出一个字符串的长度l,在求出一个串时的方法数a1,那么家下来k-1接上的时候会成一个等比数列,即:a1,a1*( 2 ^ l ),a1*( 2 ^ (2l) ),…………,
a1*( 2 ^ (k-1)l )。那么如果根据等比数列前n项和的公式求出:sum=a1 * ( 2 ^ ( k* l) -1 )/( 2 ^ l -1 )。这样做的话会wa掉,因为有除法,分子要对max取模,那么就不一定能够整除分母。下面采用费马小定理求逆元的办法。
设分子为a,分母为b。那么sum=a1* a/b%max。设b的逆元是p,那么b*p=1。那么,sum=a1*a*p%max。那接下来胖怎么求呢?
根据费马小定理:a ^ (p-1)=1(mod p),前提是a,p互质。有题知:b和max互质,则b ^ (max-1)=1(mod max)。所以b*b^(max-2)=1;即p=b^(max-2)。
所以,sum=((a1*a)%max)*(b ^ (max-2))%max,其中a=2 ^ ( k* l) -1,b=2 ^ l -1。式子中所有的幂数都要用快速幂来求。
这道题,受益良多啊~~~快速幂更加深了印象,还学会了费马小定理~~~。
code:
#include
#include
#include
#include
#include
using namespace std;
#define MAX 1000000007
__int64 mode(__int64 a, __int64 n)
{
__int64 t = a;
__int64 ans = 1;
while(n)
{
if(n & 1)
{
ans = ans * t%MAX;
}
n >>= 1;
t = t * t%MAX;
}
return ans;
}
int main()
{
__int64 k,t1,t2;
string s;
cin >> s >> k;
__int64 i,ans=0,sum=1;
__int64 l1=s.length();
for(i=l1-1; i>=0; i--)
{
if(s[i]=='0'||s[i]=='5')
ans=(ans+mode(2,i))%MAX;
}
ans=((ans*(mode(2,l1*k)-1))%MAX)*mode(mode(2,l1)-1,MAX-2)%MAX;
cout << ans%MAX << endl;
return 0;
}
D题:Block Tower
题意:
.代表空地,#代表洞,空地可以建塔。塔分为两种:蓝色的塔,可以建在空地上。红色的塔,必须周围有蓝色的才可以建。还可以将蓝色的拆掉在建红色的。求建成红色塔最多的过程~~~,注意Note, that you shouldn't minimize the number of operations这句话,说明答案不是唯一的~~~
思路:dfs搜素就可以了,
code:
#include
#include
#include
#include
using namespace std;
char map[550][550];
int vis[550][550]={{0}};
char c[100000005];
int x[100000005];
int y[100000005];
int m,n;
int sum=0;
void dfs(int a,int b,int t)
{
if(a<1||a>n||b<1||b>m)return ;
c[sum]='B';
x[sum]=a;
y[sum]=b;
sum++;
vis[a][b]=0;
if(vis[a-1][b])
dfs(a-1,b,1);
if(vis[a+1][b])
dfs(a+1,b,1);
if(vis[a][b-1])
dfs(a,b-1,1);
if(vis[a][b+1])
dfs(a,b+1,1);
if(t)
{
c[sum]='D';
x[sum]=a;
y[sum]=b;
sum++;
c[sum]='R';
x[sum]=a;
y[sum]=b;
sum++;
}
}
int main()
{
int i,j;
cin >> n >> m;
for(i=1; i<=n; i++)
for(j=1; j<=m; j++)
{
cin >> map[i][j];
if(map[i][j]=='.')
vis[i][j]=1;
}
for(i=1; i<=n; i++)
for(j=1; j<=m; j++)
{
if(vis[i][j])
dfs(i,j,0);
}
cout << sum << endl;
for(i=0; i
E题:Axis Walking
题意:有n个数,那么由这n个数到达这些数的总和,但是不能到达给出的指定的数。求出共有多少种方式到达?
思路:状态压缩DP,还没有懂,先转过来~~~~
01.#include
02.#include
03.#include
04.#include
05.#include
06.#include
07.#include
08.#include
09.#include
10.#include
11.#include