Codeforces Round #372 (Div. 1) A. Plus and Square Root 解题报告

Codeforces Round #372 (Div. 1) A. Plus and Square Root 解题报告

A. Plus and Square Root

Codeforces Round #372 (Div. 1) A. Plus and Square Root

ZS the Coder is playing a game. There is a number displayed on the screen and there are two buttons, ’ + ’ (plus) and ‘根号’ (square root). Initially, the number 2 is displayed on the screen. There are n + 1 levels in the game and ZS the Coder start at the level 1.

When ZS the Coder is at level k, he can :

  1. Press the ’ + ’ button. This increases the number on the screen by exactly k. So, if the number on the screen was x, it becomes x + k.
  2. Press the ‘根号’button. Let the number on the screen be x. After pressing this button, the number become 根号x. After that, ZS the Coder levels up, so his current level becomes k + 1. This button can only be pressed when x is a perfect square, i.e. x = m2 for some positive integer m.

Additionally, after each move, if ZS the Coder is at level k, and the number on the screen is m, then m must be a multiple of k. Note that this condition is only checked after performing the press. For example, if ZS the Coder is at level 4 and current number is 100, he presses the ‘根号’ button and the number turns into 10. Note that at this moment, 10 is not divisible by 4, but this press is still valid, because after it, ZS the Coder is at level 5, and 10 is divisible by 5.

ZS the Coder needs your help in beating the game — he wants to reach level n + 1. In other words, he needs to press the ‘根号’ button n times. Help him determine the number of times he should press the ’ + ’ button before pressing the ‘根号’ button at each level.

Please note that ZS the Coder wants to find just any sequence of presses allowing him to reach level n + 1, but not necessarily a sequence minimizing the number of presses.

题目大意:

当前你手中有一个数”2”(最开始的num)。从第一回合开始,在第m个回合中,你要对这个数做k次加法,使这个数变为k*m+num(num为上一回合操作完成后得到的数),并将其开方,得到一个新的num。要求这个新的num整除于m+1,同时输出每回合进行加法操作的次数k。


解题:

终于开始写csdn了,从大学开始真的是要努力了,关于codeforces的解题报告就从这道水题开始吧。
这道题一开始真的是没有什么头绪,虽然感觉是道数学题,可没什么想法,只好写了个小枚举找找灵感。大体就是枚举i,使((m+1)*(m+1)*i*i-num)%m==0这样的倒推枚举,不过如果这样做时间是肯定要爆的。
之后是看了一下m=10000左右的数据, 挺惊喜的发现大部分的最小的i都等于当前的回合数m,然后就直接把这个现象拿过来用重写了循环,只是m=1的时候需要特判一下。
代码如下:

#include 
using namespace std;

long long n,k;

int main()
{
scanf("%lld",&n);
for(long long m=1;m<=n;m++)
 {
  if(m==1) k=2;
  else k=m*m*(m+2)+1;
  printf("%lld\n",k);
}
return 0;  
}

之后提交不出意外的一次过了,虽然是道水题。


证明:当k=m^2*(m+2)+1(m!=1)或2(m=1),得到的num一直符合题意

当m=1 时,k=2,新的num为2,成立。
假设m=x-1时成立,此时的num为(x-1)*x,当m=x时,若k=m^ 2* (m+2)+1,可求得新的num为x^2*(x+1)^2,整除于x+1。
综上,当k=m^2*(m+2)+1(m!=1)或2(m=1),得到的num一直符合题意。

你可能感兴趣的:(codeforces,acm,codeforces,acm,c++)