安工第六届程序设计大赛(复赛)

本文解析了五道编程挑战题目,包括键盘错位字符纠正、开灯问题、鞭炮声计数、素数环构建及次品箱识别。通过实际代码展示了不同问题的解决思路和技术应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



比赛前老师说不让拿书,都是我们没见过的题,看到题后我笑了,基本上都是似曾相识的。。
1. 把手放在键盘上时,稍不注意就会往右错一位,这样, Q 就编程变成了 W, J 就变成了 K 等, 电
脑键盘如图所示, (错位字符串内容限定在红线包含区域,且不包含上档键)
编程实现:输入一个错位后的字符串,输出本来想打的句子。
如错位字符串为: OS,GOMR YPSFU/,输出: I AM FINE TODAY


图就不给了,本题为小白书(算法竞赛入门经典)69页的WERTYU。
解决:
1.查找;
2.输出。

代码:

#include<stdio.h>
char *s = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";
int main()
{
    int i, c;
    while((c = getchar()) != EOF){
        for(i = 1; s[i] && s[i] != c; i++);
        if(s[i]) putchar(s[i - 1]);
        else putchar(c);
    }
    return 0;
}

2.开灯问题: 有 n 盏灯, 编号为 1~n, 第一个人把所有灯打开, 第 2 个人按下所有是 2 的倍数的开
关, 第 3 个人按下所有编号为 3 的倍数的开关(其中关着的灯将被打开, 打开的灯将被关闭), 以此
类推,一共有 k 个人,问最后哪些灯开着?输入 n k,输出开着灯的编号。(k<=n<=100
如: n k 分别为 7 3,则输出为 1 5 6 7

此题为南阳理工OJ第77题,模拟一下就行了

代码:

#include<stdio.h>
#include<string.h>
int a[1010];
int main()
{
    int n,k,s,i,j;
    memset(a,1,sizeof(a));
    scanf("%d%d",&n,&k);
    for(i = 2; i <= n; i++)
        for(j = 2; j <= k; j++)
            if(i % j == 0)
                a[i] =! a[i];
    for(i = 1; i <= n; i++)
        if(a[i])
            printf("%d ",i);
    printf("\n");
    return 0;
}

3.甲乙丙丁同时开始放鞭炮, 甲每隔t1 秒放一次, 乙每隔 t2 秒放一次, 丙每隔 t3 秒放一次, 丁每隔
t4 秒放一次,每人各放 n 次,求共听到多少次鞭炮声(当几个鞭炮同时炸响,只算一次响声,第一
次响声是在 0 秒)? 如: t1=7,t2=5,t3=6,t4=4,n=10,则结果为 28

这题当时一看懵了一下,类似第二题,同样模拟

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[1010];
int main()
{
    int n, t1, t2, t3, t4;
    scanf("%d%d%d%d%d", &t1, &t2, &t3, &t4, &n);
    for(int i = 0; i < n; i++){
        a[i * t1] = 1;
        a[i * t2] = 1;
        a[i * t3] = 1;
        a[i * t4] = 1;
    }
    int s = 0;
    int Max = max(max(t1, t2), max(t3, t4));
    for(int i = 0; i <= (n - 1) * Max; i++)
        if(a[i])
            s++;
    printf("%d\n", s);
    return 0;
}

题中给的数据运行结果为29,比赛后也有很多人说是29,这个也许是周老师。。。

4.输入正整数n(n<30),把整数1,2,3, ……,n组成一个环,使得相邻两个整数之和均为素数,输出时
从整数 1 开始逆时针排列。
如输入 n 6,则输出: 1 4 3 2 5 6 n 8 时,输出为 1 2 3 8 5 6 7 4

素数环,小白书126页,南阳理工OJ488题,当时这题卡了很长时间,回溯算法掌握的还不是太牢。再敲一遍代码,加深印象吧!

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int isp[100], A[20], vis[20];
int n, ok;

int is_prime(int n)
{
    for(int i = 2; i * i <= n; i++) if(n % i == 0) return 0;
    return 1;
}

void dfs(int cur)
{
    if(ok) return;          //只输出一组答案
    if(cur == n && isp[A[0] + A[n - 1]]){
        for(int i = 0; i < n; i++) printf("%d ", A[i]);     //打印方案
        printf("\n");
        ok = 1;
    }
    else for(int i = 2; i <= n; i++)        //尝试放置每个数i
        if(!vis[i] && isp[i + A[cur - 1]]){     //如果i没用过,且与前一个数之和为素数
            A[cur] = i;
            vis[i] = 1;         //记为已经使用
            dfs(cur + 1);       //判断下一个
            vis[i] = 0;         //清除标记
        }
}
int main()
{

    scanf("%d", &n);
    for(int i = 2; i <= n * 2; i++) isp[i] = is_prime(i);   //生成素数表,加快后续判断
    A[0] = 1;       //第一个数为 1
    vis[1] = 1;
    dfs(1);
    return 0;
}

5.10 箱产品每箱有 1000 件,正品每件 100 克。其中只有一箱是次品,次品每件比正品轻 10 克,
问能否用秤只称一次,就找出哪一箱是次品。
这题当时没做出来,一个思维题,比赛结束后听学长一讲就清楚了。

解法:

将十箱产品标号为1-10,取产品,标号为1的那箱取1件,标号为2的那箱取2件。。。。标号为几就取几件。

称一下所取物品的总质量,如果全为正品,则总质量为5500,

如果1号箱是次品,则总质量为5490,如果2号箱是次品,则为5480,

于是,设最后的总质量为sum,第x箱为次品,则 x = (5500 - sum) / 10.

最后讲题的时候学长告诉我们这是一种解题方法,数字信息化,感觉好强大!

以后的路还很长,不管如何都要坚持下去。

路漫漫其修远兮,吾将上下而求索。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值