Advertisement

算法竞赛入门经典(第2版)第3章

阅读量:
开灯问题

开灯问题,有n盏灯,编号为1~n。第一个人把所有灯都打开,第二个人按下所有编号为2的倍数的开关(这些灯将被关掉),第三个人按下所有编号为3的倍数的开关(其中关掉的灯将被打开,开着的灯将被关闭),以此类推。一共有k个人,问最后有哪些灯开着?输入n和k,输出开着的灯的编号。k<=n<=1000。
样例输入:
7 3
样例输出:
1 5 6 7
【分析】
用a[1],a[2],··· ,a[n]表示编号为1,2,3,··· ,n的灯是否开着。模拟这些操作即可。

复制代码
    #include<iostream>
    int main()
    {
    	int n, k, first = 1;
    	int a[10]{};
    	std::cin >> n >> k;
    	for (int i = 1; i <= k; i++)
    		for (int j = 1; j <= n; j++)
    			if (j % i == 0) a[j] = !a[j];
    	for (int i = 1; i <= n; i++)
    		if (a[i])
    		{
    			if (first)
    				first = 0;
    			else
    				std::cout << " ";
    			std::cout << i;
    		}
    	return 0;
    }
竖式问题

找出所有形如abc*de(三位数乘以两位数)的算式,使得在完整的竖式中,所有数字都属于一个特定的数字集合。输入数字集合(相邻数字之间没有空格),输出所有竖式。每个竖式前应有编号,之后应有一个空行。最后输出解的总数。具体格式见样例输出(为了便于观察,竖式中的空格改用小数点显示,但你的程序应该输出空格,而非小数点)。

样例输入:2357

样例输出:

<1>
…775
X…33


.2325
2325.


25575
The number of solutions = 1

复制代码
    #include<stdio.h>
    #include<string.h>
    int main(void)
    {
        char s[20], buff[99];
        int count = 0;
        scanf("%s", s);
        for (int abc = 101; abc <= 999; abc++)
        {
                for (int de = 11; de <= 99; de++)
                {
                        int x = abc * (de % 10);
                        int y = abc * (de / 10);
                        int ok = 1;
                        sprintf(buff, "%d%d%d%d%d", abc, de, x, y, abc * de);
                        for (int i = 0; i < strlen(buff); i++)
                                if (strchr(s, buff[i]) == NULL)
                                        ok = 0;
                        if (ok)
                        {
                                printf("<%d>\n", ++count);
                                printf("%5d\n", abc);
                                printf("X%4d\n", de);
                                printf("-----\n");
                                printf("%5d\n", x);
                                printf("%5d\n", y);
                                printf("-----\n");
                                printf("%5d", abc * de);
                        }
                }
        }
        printf("The number of solutions = %d\n", count);
        return 0;
    }
Tex 中的引号(Tex Quotes,Uva 272)
复制代码
    在Tex中,左双引号是“``”,右双引号是"’’"。输入一篇包含双引号的文章,你的任务是把它转换成TeX的格式。
    样例输入:
    "To be or not to be," quoth the Bard,"that is the question".
    样例输出:
    ``To be or not to be,'' quoth the Bard,``that is the question''
复制代码
    #include<stdio.h>
    int main()
    {
    	int c, q = 1;
    	while ((c = getchar()) != EOF)
    	{
    		if (c == '"')
    		{
    			printf("%s", q ? "``" : "''");
    			q = !q;
    		}
    		else
    			printf("%c", c);
    	}
    	return 0;
    }
WERTYU (WERTYU, UVa10082)

WERTYU 把手放在键盘上,稍不注意就会往右错一位。这样,输入Q会变成输入W,输入J会变成输入K等。
输入一个错位后敲出的字符串(所有字母均大写),输出打字员本来想打出的句子。
输入保证合法,即一定是错位之后的字符串。例如输入中不会出现大写字母A.
样例输入;
O S, GOMR YPFSU/
样例输出:
I AM FINE TODAY.

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

输入一个字符串,判断它是否为回文以及镜像串。输入字符串保证不含数字0.所谓回文串,就是反转之后原串相同,如abba和madam。所谓镜像串,就是左右镜像之后和原串相同,如2S和3AIAE。注意,并不是每个字符在镜像之后都能得到一个合法字符,本题中,每个字符的镜像如下所示,(空白项表示该字符镜像后不能得到一个合法的字符)。
在这里插入图片描述输入的每行包含一个字符串(保证只有上述字符。不含空白字符),判断它是否为回文 串和镜像串(共4种组合)。每组数据之后输出一个空行。
样例输入:
NOTAPALINDROME
ISAPALINILAPASI
2A3MEAS
ATOYOTA

样例输出:
NOTAPALINDROME – is not a palindrome.

ISAPALINILAPASI – is a regular palindrome.

2A3MEAS – is a mirrored string.

ATOYEOTA – is a mirrored palindrome.

复制代码
    #include<stdio.h>
    #include<string.h>
    #include<ctype.h>
    const char * rev = "A   3  HIL JM O   2TUVWXY51SE Z 8";
    const char * msg[] = {"not a palindrome", "a regular palindrome", "a mirrored string", "a mirrored palindrome"};
    
    char r(char ch)
    {
        if (isalpha(ch))        return rev[ch - 'A'];
        return rev[ch - '0' + 25];
    }
    
    int main()
    {
        char s[30];
        while (scanf("%s", s) == 1)
        {
                int len = strlen(s);
                int p = 1, m = 1;
                for (int i = 0; i < (len + 1) / 2; i++ )
                {
                        if (s[i] != s[len - 1 - i]) p = 0;
                        if (r(s[i]) != s[len - 1 - i]) m = 0;
                }
                printf("%s -- is %s.\n\n", s, msg[m*2+p]);
        }
        return 0;
    }

全部评论 (0)

还没有任何评论哟~