Description
The function f(n, k) is defined by f(n, k) = 1k + 2k + 3k +...+ nk. If you know the value of n and k, could you tell us the last digit of f(n, k)?
For example, if n is 3 and k is 2, f(n, k) = f(3, 2) = 12 + 22 + 32 = 14. So the last digit of f(n, k) is 4.
Input
The first line has an integer T (1 <= T <= 100), means there are T test cases.
For each test case, there is only one line with two integers n, k (1 <= n, k <= 109), which have the same meaning as above.
Output
For each test case, print the last digit of f(n, k) in one line.
这道题就是一道快速幂加上打表的一道题。
对于每一次求幂的最后一位,用快速幂,然后用打表来找规律,因为这道题是有周期的。所以最后只要找到那个周期就好。
#include<stdio.h>
#include<string.h>
int powermod(int n,int k){
int ans=1;
n=n%10;
while(k){
if(k%2) ans=(ans*n)%10;
k=k/2;
n=(n*n)%10;
}
return ans;
}
int main(){
int T,i,j,n,k;
scanf("%d",&T);
while(T--){
int f[1111]={0};
int ans=0,t=0;
scanf("%d%d",&n,&k);
for(i=1;i<=1000;i++){
t=powermod(i,k);
f[i]=(t+f[i-1])%10;
}
int temp,flag;
for(i=1;i<=1000;i++){
flag=1;
for(j=i+1;j<=1000;j++){
if(f[j]!=f[j%i]) {flag=0; break;}
}
if(flag) {temp=i; break;}
}
ans=n%temp;
printf("%d\n",f[ans]);
}
}
Description
彩色砖块是一个有趣的小游戏。游戏界面是一个N*M的方格,从上至下依次记为第1行,第2行,……,第N行,从左至右依次记为第1列,第2列,……,第M列,每个格子中有一个非负整数a,a大于0表示该格子中有一个颜色为a的砖块,否则该方格是空的。
游戏的规则很简单:点击一个空格子o,然后以o为中心,形成一个十字线,如果十字线能连接到的两个或以上相同颜色的方块就能将这些颜色相同的方块全部打碎,并累加与打碎的方块数相同的得分。如果十字线连到的相同颜色的方块不足两个,则此次操作无效。更多详细的信息可以参考样例。
小明最近很痴迷于这款游戏,想在这个游戏中玩出高分,现在给出你游戏的方格图,并给出小明的操作,每个操作包含两个整数x, y,表示小明点击了第x行第y列的格子,你需要计算出小明的最终分数。注意:小明有可能不小心点到了有方块的格子,这样的操作是无效的,不对其做任何处理。
Input
输入的第一行包含一个整数T (1 <= T <= 100),表示接下来一共有T组测试数据。
对于每组测试数据,第一行包含两个整数N, M (1 <= N, M <= 30),含义同上。接下来N行每行均包含M个整数,描述了游戏界面的情况。数据保证格子中的整数均在[0, 9]范围内。接下来一行包含一个整数P (1 <= P <= 100),表示小明操作的次数。接下来P行按时间先后顺序给出了小明的P次操作,每行均包含两个整数x, y (1 <= x<= N, 1 <= y <= M),表示小明点击了第x行第y列的格子。
Output
对于每组测试数据,用一行输出一个整数,表示小明的最终得分。
对于每组测试数据,小明的初始得分均为0。
这道题是一道水题,但是要注意写法以及每次如果消掉了那个方块,那么注意要把原先那个方块的位置标记为0方便下次操作,然后最重要的部分就是来判断4个方块中有几个是同种颜色且数量大于1且不是0.
#include<stdio.h>
#include<string.h>
int a[50][50];
int x1,x2,y1,y2,x,y;
int change(int j){
if(j==0) a[x1][y]=0;
if(j==1) a[x2][y]=0;
if(j==2) a[x][y1]=0;
if(j==3) a[x][y2]=0;
}
int main(){
int T,i,j,k,n,m;
scanf("%d",&T);
while(T--){
memset(a,0,sizeof(a));
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&a[i][j]);
int ans=0,p;
scanf("%d",&p);
while(p--){
scanf("%d%d",&x,&y);
if(a[x][y]) continue;
int ss[11]={0};
//往上寻找;
for(i=x-1;i>=1;i--){
if(a[i][y]) {ss[0]=a[i][y]; break;}
}
if(i!=0) x1=i;
else x1=1;
//往下寻找;
for(i=x+1;i<=n;i++){
if(a[i][y]) {ss[1]=a[i][y]; break;}
}
if(i!=n+1) x2=i;
else x2=n;
//往右寻找;
for(j=y+1;j<=m;j++){
if(a[x][j]) {ss[2]=a[x][j]; break;}
}
if(j!=m+1) y1=j;
else y1=m;
//往左寻找;
for(j=y-1;j>=1;j--){
if(a[x][j]) {ss[3]=a[x][j]; break;}
}
if(j!=0) y2=j;
else y2=1;
int flag=0,num=0;
for(i=0;i<4;i++){
flag=0;
if(ss[i]){
for(j=i+1;j<4;j++){
if(ss[i]==ss[j]) {flag=1; ss[j]=0; change(j); num++;}
}
}
if(flag) {ss[i]=0; change(i); num++;}
}
if(num>1) ans+=num;
}
printf("%d\n",ans);
}
}
我一开始的错误代码是这样想的,把四个方向的方块保存于ss数组中,然后sort一遍,判断前后两个是否相等,但是我忽视了一点就是sort之后ss数组的顺序会发生改变。
所以还是for两遍来判断吧,反正也只有4个点。
Description
在一个美丽的小岛上住着一群变色龙:其中有X只变色龙是红色的,Y只变色龙是绿色的,Z只变色龙是蓝色的。
每个时刻会有两只不同颜色的变色龙相遇,相遇后他们会同时变成第三种颜色。比如,如果一只红色的变色龙和一只蓝色的变色龙相遇了,他们就会同时变成绿色的变色龙,如果一只绿色的变色龙和一只蓝色的变色龙相遇了,他们就会同时变成红色的变色龙,等等。
那么最后是否有可能所有的变色龙都是同一种颜色呢?
Input
输入的第一行包含一个整数T (1 <= T <= 100),表示接下来一共有T组测试数据。
每组数据占一行,包含三个整数X, Y, Z (1 <= X, Y, Z <= 109),含义同上。
Output
对于每组测试数据,如果最后有可能所有的变色龙都是同一种颜色,用一行输出“Yes”(不包括引号),否则输出“No”(不包括引号)。
Sample Input
4 1 1 1 1 2 3 7 1 2 3 7 5
Sample Output
Yes No Yes No
Hint
对于样例1:其中一种可能的变化方式为:1 1 1 --> 0 2 0。
对于样例3:其中一种可能的变化方式为:7 1 2 --> 6 3 1 --> 5 5 0 --> 4 4 2 --> 3 3 4 --> 2 2 6 --> 1 1 8 --> 0 0 10。
这是一道考验思维的题,我想到了当有两个颜色种类的变色龙数量相同时,那么最终肯定能变化成全部相同的颜色。
那么什么时候可以变成数量相同呢?
这里 我们假设颜色1有x条,颜色2有y条,颜色3有z条。
那么这里我们要让颜色1与颜色2的数量尽可能的相等,
首先,我们让1与3相碰a条,然后2就有y=y+2a条了,x=x-a。
然后我们2与3相碰b条,那么x=x-a+2b , y=y+2a-b;
因为要使1与2的条数相等,那么最后得到 y-x=3*(b-a);
所以最后的差值为3的倍数就好了。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main(){
int T,i,j;
int a[3]={0};
scanf("%d",&T);
while(T--){
memset(a,0,sizeof(a));
scanf("%d%d%d",&a[0],&a[1],&a[2]);
sort(a,a+3);
if((a[1]-a[0])%3==0||(a[2]-a[1])%3==0||(a[2]-a[0])%3==0) puts("Yes");
else puts("No");
}
}
Description
There is a pile of N pebbles initially. Alice and Bob are playing a taking pebbles game as follows:
Alice and Bob moves by turns, Alice moves first. For each move, the player can takes away at least one and at most half of the pebbles remained (“at most half” means you can take way at most k (k >= 1) pebbles if there are 2*k or 2*k+1 pebbles remained). If there is only one pebble remained, the player can also take away this pebble. The player who takes away the last pebble wins.
If Alice and Bob are both clever enough, and they both want to be the winner, who will win?
Input
The first line has one integer T (1 <= T <= 200), means there are T test cases.
For each test case, there is only one line with an integer N (2 <= N <= 109), means the number of pebbles initially.
Output
For each test case, print “Alice” (without quotation marks) in one line if Alice will win. Otherwise print “Bob” (without quotation marks) instead.
Sample Input
5 2 3 4 5 6
Sample Output
Bob Alice Alice Bob Alice
这道题目的大致意思是:
就是有n个石头,然后a与b分别轮流取,每次都能取至少一块,或者最多只能取k块(如果还余下2*k块或者2*k+1块)。但是如果只有最后一块剩下,那么轮到的那个人就可以直接拿走那一块,拿到最后一块的人为获胜者。
这个就是大致的图解,图中的数字均代表余下的数量,如果余下2个的话,那么肯定就是loser,依次往上类推,在k+1到2*k间的数都能是winner,然后再继续往上推。
这个想法超棒,而且图也能很好的让人理解。十分感谢我们集训队的一个朋友。
#include<stdio.h>
#include<string.h>
int main(){
int T,i,j,n;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
if(n==2) {puts("Bob"); continue;}
else{
int x=2,flag=0;
while(x<n){
x=x*2+1;
if(x==n) {flag=1; break;}
}
if(flag) puts("Bob");
else puts("Alice");
}
}
}
Description
There is an integer sequence with N integers. You can use 1 unit of cost to increase any integer in the sequence by 1.
Could you tell us the least units of cost to achieve that, the absolute value of difference between any two adjacent integers is not more than D?
Input
The first line has one integer T, means there are T test cases.
For each test case, the first line has two integers N, D (1 <= N <= 105, 0 <= D < 109), which have the same meaning as above. The next line has N integers describing the sequence. Every integer in this sequence is in range [0, 109).
The size of the input file will not exceed 5MB.
Output
For each test case, print an integer in one line, indicates the desired answer.
Sample Input
3 5 2 1 3 5 3 5 5 1 1 2 3 5 6 5 2 1 7 3 5 9
Sample Output
0 3 8
这道题的意思是:
给你一串数列和一个数d,然后每次你都可以进行一次如下操作,就是对数列中的任意一个数进行加1的操作。
要求就是,对与给定数列的任意两个相邻数字,使它们两个只差不能超过d这个数字,然后问你最多要进行几次加1的操作才能使任意两个之差满足小于等于d这个条件。
暴力for两遍可以过,但是有些细节要注意处理。
#include<stdio.h>
#include<string.h>
#include<math.h>
long long a[111111];
int main(){
int T,i,j,k;
long long n,d,sum;
scanf("%d",&T);
while(T--){
sum=0;
scanf("%lld%lld",&n,&d);
memset(a,0,sizeof(a));
for(i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(i=1;i<n;i++){
if(fabs(a[i]-a[i+1])<=d) continue;
//当后面的小于前面的那个时,那么不用进行下面的前判;
else if(a[i+1]<a[i]){
sum+=(a[i]-a[i+1])-d; //这里的优化,就是直接做差减一下就好了,注意sum的求要放在a数组的值改变之前的;
a[i+1]=a[i]-d;
}
//当前面的小于后面的时,才要进行前判(就是判断前面的)
else if(a[i]<a[i+1]){
sum+=a[i+1]-a[i]-d;
a[i]=a[i+1]-d;
for(j=i;j>1;j--){
//当满足这个条件时,直接就可以跳出循环了,因为我们对于前面已经判断好了;
if(fabs(a[j]-a[j-1])<=d)
break;
if(a[j]>a[j-1]){
sum+=a[j]-a[j-1]-d;
a[j-1]=a[j]-d;
}
}
}
}
printf("%lld\n",sum);
}
}
注意要用__int64;
附上比赛题目链接:
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=72892#overview