滁州学院1024程序设计大赛题解

1,145 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第24天,点击查看活动详情
本文已参与「新人创作礼」活动,一 起开启掘金创作之路

首战

这是一道博弈论的经典题我们可以这样理解每个人拿棋子的范围是[1,m][1,m]那么对于每一次拿取就可以保证两人拿取棋子之和为m+1m+1所以我们只需要判断nn能否被m+1m+1整除即可

#include <stdio.h>

int main() {
    int n,m;
    scanf("%d %d",&n,&m);
    if(n % (m + 1)) printf("Defeat");
    else printf("Victory");
}

卡片

我们发现对于这题如果我们可以裁剪一次那么我们纸片个数就会乘2所以暴力即可

#include <stdio.h>

int main(){
    int T; scanf("%d",&T);
    while( T -- ) {
        int w,h,n; scanf("%d %d %d",&w,&h,&n); 
        int res = 1;
        while(w % 2 == 0) {
            res = res * 2;
            w  = w / 2;
        }
        while(h % 2 == 0) {
            res = res * 2;
            h  = h / 2;
        }
        if(res < n) printf("NO\n");
        else printf("YES\n");
    }
}

监狱

数字反转我们可以模拟数字增位的过程例如 :如果想将11变成11x只需要把11乘10然后加x即可代码只需要这样实现就行

#include <stdio.h>

int main()
{
    int n; scanf("%d",&n);
    int res = 0;
    while(n) {
        res *= 10;
        res += n % 10;
        n /= 10;
    }
    printf("%d",res);
}

冲锋

这算是最难的一道题了是一道简单dp
我们发现当我们处于ii位置时是可以由jj位置跳过来的(ikji1)(i-k\leq j\leq i-1)注意(1ik)(1\leq i-k)递推公式是f[i]=min(f[i],f[ik]+h[i]h[ik])f[i] =min(f[i],f[i-k]+|h[i]-h[i-k]|)

#include <stdio.h>
#include <math.h>

int h[100010],f[100010];

int min(int a,int b) {
    return a > b ? b : a;
}


int max(int a,int b) {
   return a > b ? a : b;
}

int main()
{
    int n,k; scanf("%d %d",&n,&k);
    for(int i = 1; i <= n; i++) scanf("%d",h + i);
    for(int i = 1; i <= n; i++) f[i] = 1e9;
    f[1] = 0;
    for(int i = 2; i <= n; i++) {
        for(int j = i - 1; j >= max(1,i - k); j --)
           f[i] = min(f[i],f[j] + abs(h[j] - h[i]));
    }
    printf("%d",f[n]);
}

签到

这是签到题根据题意进行处理就行

#include <stdio.h>

int main(){
    int n; scanf("%d",&n);
    if(n%7&&n%17&&n%37) printf("NO");
    else printf("YES");
}

炸鱼

这是一道分支的题目。根据输入的nn然后根据对应的公式输出就行

#include <stdio.h>

int main()
{
    int n,r; scanf("%d %d",&n,&r);
    if(n == 1) printf("%d",r * r * 2);
    else if(n == 2) printf("%d",r * r * r);
    else printf("%d",r * r * r + r * r  + r);
}

寻路

这题是一道找规律的题目 image.png 这是不在边界的三个点的移动轨迹。
然后我们可以发现对于‘L’的拐点的哪个点来说,它斜方距离它距离为1的点是到达不了的。所以我们只需要跟这个拐点的轨迹来,我们可以从图中发现它可以到达的点的坐标的奇偶性是相等的,因为它每次移动都是往四周移动两个格子是不会改变它本来的奇偶性的。然后我们可以发现它斜方距离它距离为1的点奇偶性和它是完全不同的所以我们就把这题变成了判断奇偶性的题目。
(有四个点是需要特判的)就是拐点在(1,1),(1,n),(n,1),(n,n)(1,1),(1,n),(n,1),(n,n)的四个点因为对于这四个点它们只能直线行走 image.png 例如(1,1)这个点它只有两种运行轨迹 image.png
其他三个点也是同理

#include <stdio.h>

int main()
{
    int n;
    scanf("%d",&n);
    int x1,y1,x2,y2,x3,y3,x4,y4;
    scanf("%d %d %d %d %d %d",&x1, &y1, &x2, &y2, &x3, &y3);
    int edx,edy;
    scanf("%d %d",&edx, &edy);
    //找拐点(x4,y4)
    if(x1 == x2) x4 = x1;
    if(x2 == x3) x4 = x2;
    if(x1 == x3) x4 = x1;
    if(y1 == y2) y4 = y1;
    if(y2 == y3) y4 = y2;
    if(y1 == y3) y4 = y1;
    if((x4 == 1||x4 == n)&&(y4 == 1||y4 == n)) {
        if(edx == x4 || edy == y4) {
            printf("YES");
        }else printf("NO");
        return 0;
    } 
    if((x4 % 2 != edx% 2)   &&( y4 % 2 != edy % 2)) printf("NO");
    else printf("YES");
    return 0;
}

破解

暴力forfor循环就行

#include <stdio.h>
int main() {
   for(int i1 = 0 ; i1 <= 1; i1 ++) 
      for(int i2 = 0; i2 <= 1; i2++)
         for(int i3 = 0; i3 <= 1; i3++)
            for(int i4 = 0; i4 <= 1; i4++)
               for(int i5 = 0; i5 <= 1; i5++)
                  for(int i6 = 0; i6 <= 1; i6++)
                     for(int i7 = 0; i7 <= 1; i7++)
                        for(int i8 = 0; i8 <= 1; i8++)
                           for(int i9 = 0; i9 <= 1; i9++)
                              for(int i10 = 0; i10 <= 1; i10++)
         {
            putchar((i1 ? 'h' : 'H'));
            putchar((i2 ? 'e' : 'E'));
            putchar((i3 ? 'l' : 'L'));
            putchar((i4 ? 'l' : 'L'));
            putchar((i5 ? 'o' : 'O'));
            putchar((i6 ? 'w' : 'W'));
            putchar((i7 ? 'o' : 'O'));
            putchar((i8 ? 'r' : 'R'));
            putchar((i9 ? 'l' : 'L'));
            putchar((i10 ? 'd' : 'D'));
            puts("");
          }
}

计数

这题是考察字符串输入和将数字字符转换为数字的我们发现将数字字符减去'0'就可以得到这个数字

#include <stdio.h>

int main() {
    int sum = 0;
    char x;
    while(scanf("%c",&x)) {
        if(x == '\n') break;
        sum += x - '0';
    }
    printf("%d\n",sum);
}

峡谷

这是一道数学题首先我们可以知道我们最少消耗的体力值是肯定是a1ak|a_1 - a_k|所以我们只需要在不影响最小消耗的情况下走过最多的点。如果aiaka_i\geq a_k那我们就可以取消绝对值如果我们现在再经过点x那么现在的消耗就变成了a1ax+axak|a_1-a_x|+|a_x-a_k|,我们发现为了不影响最小消耗值akaxa1 a_k \leq a_x\leq a_1 。这样我们就可以去掉绝对值变成a1ax+axaka_1-a_x+a_x-a_k ,axa_x的影响就被消除了所以我们发现我们到达的台阶的只需要在[a1,ak][a_1,a_k]之间就行,反之同理。

#include <stdio.h>

#include <math.h>

int a[200010];

int main()
{

  int n; scanf("%d",&n);
  for(int i = 1; i <= n; i++) scanf("%d",a + i);
  int k; scanf("%d", &k);
  int num = 0;
  for(int i = 1; i <= n; i++) if((a[i] >= a[1] && a[i] <= a[k])||(a[i] >= a[k] && a[i] <= a[1])) num ++;
  printf("%d\n",num-1);
  printf("%d\n",abs(a[1] - a[k]));
}