集训到目前学到的东西

一月十八日对集训的总结

啊,已经集训三天了,该认真写次总结了。

就先写下我这几天做过的题的做法与错误的原因吧。

一.武士之魂2:不是假发是桂!

这题可把我恶心坏了,感觉这题其实也存粹是个高中数学题,感觉只有用脑想想就做得出来(可惜我没有这玩意儿),开始的时候我一直想找出每次走的规律,然后再写出代码,但这个规律我硬是半天没找出来,哎结果发现就是到简简单单的题。

这个题是用排列组合去做的,

最主要还是理解假设它为m*m的矩形,那么他总共要走2m条路(首先它是个边长为m的正方形,所以总共为路程就为m+m),然后我们只需要选择向上走m的方法就可以了,于是就想到了Cm 2m,于是只需要输出Cm 2m就对了。

下面看代码:

 

 1 #include<stdio.h>
 2 #include<math.h>
 3 long long tl(long long n)
 4 {
 5     if(n == 1) return 1;
 6     else return n = n*tl(n-1);
 7 }
 8 int main()
 9 {
10     long long n;
11     scanf("%lld",&n);
12     for(long long i = 0;i<n;i++){
13         long long m,ret;
14         scanf("%lld",&m);
15         ret = tl(2*m)/tl(m)/tl(m);
16         printf("%lld\n",ret);
17     }
18     return 0;
19 }  

下面我还想说说这几天看到的一个输入与输出问题——%l64d与%lld,这只是我的见解,可能有错误,如果题上要求你用%lld输入输出的话,那么只能用long long,而不能用int。而当为%l64d时,我们既可以用int也可以用long long,当然我看网上说可以用cint和cout来代替输入输出。

一.区间回文数

http://www.fjutacm.com/Problem.jsp?pid=1113

这个题呢我觉得主要还是要知道怎样来缩小时间复杂度,我开始做也是一直时间超限。

思路:做这个题我们要抓住回文数的特征,回文数倒叙后他还是原来那个数,所以如果它是奇数,他肯定会关于最中间的数对称,如果它是偶数,它会关于正中间对称,所以我们可以先找出这个数然后再遍历看是否在所求区间内就可以达到求区间内回文数的个数的目的。

方法一:我们先从1到9999中找一个数,然后将它倒叙并变为原来的1e5,这样后我们再从1到9之间选个数然后乘以1e4然后加到刚才乘出来的那个数,然后再从所输入的区间中遍历,看是否有这个数,有就cnt++;

 1 #include<stdio.h>
 2 int main()
 3 {
 4     int a,b;
 5     while(~scanf("%d%d",&a,&b)) {
 6         int cnt = 0;
 7         for(int i = 1;i<=9999;i++) {
 8             int x = (i%10)*100000000+(i/10%10)*10000000+(i/100%10)*1000000+(i/1000%10)*100000+i;
 9             for(int i = 0;i<=9;i++) {
10                 int y;
11                 y = x + i*10000;
12                 if(y>=a && y<=b) cnt++;
13             }
14         }
15         printf("%d\n",cnt);
16     }
17     return 0;
18 }

方法二:我们可以从0到9之间选择一个数,重复五遍然后我们分别将它乘以特定的倍数,这样我们只嵌套了五个for时间会大幅度缩小也就不会有时间超限的问题了。

 1 #include<stdio.h>
 2 int main()
 3 {
 4     long long l,r,x;//cnt为回文数的个数;
 5     while(~scanf("%lld%lld",&l,&r)) {
 6         long long cnt = 0;
 7         for(int a = 0;a<=9;a++)
 8             for(int b = 0;b<=9;b++)
 9                 for(int c = 0;c<=9;c++)
10                     for(int d = 0;d<=9;d++)
11                         for(int e = 0;e<=9;e++)
12                         {
13                             x = a*100000000+b*10000000+c*1000000+d*100000+e*10000+d*1000+c*100+b*10+a;//创造一个回文数
14                             if(x>=l && x<=r) cnt++;
15                         }
16         printf("%lld\n",cnt);
17     }
18     return 0;
19 }

但写这题时我还犯了个错误,我们在每轮循环时都应该将计数cnt重置为零,不然就会一直答案错误(一个很简单的错误却让我找了一下午)。

posted @ 2021-01-18 20:17  potentia1  阅读(69)  评论(0)    收藏  举报