紫书第三章 字符串与字符(例题与习题)

字符串与字符常用函数:

char *strcat(char *s1,const char *s2); //把s2拷贝到s1尾部
char *strncat(char *s1,const char *s2,int n); //拷贝n个s2的字符到s1的尾部
char *strstr(const char *s1,const char *s2); //返回s1字符串中s2字符串第一次出现的位置,找不到返回null
char *strchr(const char *s1,int s); //返回字符串中s第一次出现的地址,找不到则返回null
char *strrchr(const char *s1,int s); //找到最后一次出现的地址
int sprintf(char *str,"",...); //将内容打印进字符串(含初始化操作),建议使用
char *strcpy(char *s1,char *s2); //把s2的内容拷贝到s1上(不含有初始化操作,所以若s1存在字符串会覆盖原有字符串,但剩余未覆盖部分扔存在)
char *strncpy(char *s1,char *s2,int n); //与上述问题相同。若s2中字符数小于n,则拷贝整个字符串,若大于等于n则拷贝n个字符,但并不会拷贝结束符!)

简单实现KMP效果(strchr与strrchr的操作可模仿)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    char a[40] = "sdshdahsjwieuw";
    char b[40] = "wieu";

    printf("%d",strstr(a,b)-(&a[0]));

    return 0;
}
//输出为9

习题

开灯问题

有n台灯,k个人,第1个人把所有灯打开,第2个把为2倍数的灯打开/关闭,第3个人把3的倍数的灯打开/关闭,同理,输出最后开着的灯。

输入:7 3
输出:1 5 6 7

书里用的是!,用异或也是可以的。

#include <bits/stdc++.h>

using namespace std;
const int maxn = 1010;
int light[maxn];

//1表示开0,0表示关(运用异或)
int main()
{
    memset(light,0,sizeof(light));
    int n, k;
    scanf("%d%d",&n,&k);


    for(int i = 2; i <= k ; i++)
    {
        for(int j = 1 ; j <= n ; j++)
            if(j%i == 0)
              light[j] ^= 01;
    }

    for(int i = 1; i <= n ; i++)
        if(!light[i])
        printf("%d ",i);

    return 0;
}

蛇形矩阵ACwing756

原题链接:https://www.acwing.com/problem/content/758/
输入两个整数 n 和 m,输出一个 n 行 m 列的矩阵,将数字 1 到 n×m 按照回字蛇形填充至矩阵中。

具体矩阵形式可参考样例。

输入格式
输入共一行,包含两个整数 n 和 m。

输出格式
输出满足要求的矩阵。

矩阵占 n 行,每行包含 m 个空格隔开的整数。

数据范围
1≤n,m≤100
输入样例:
3 3
输出样例:
1 2 3
8 9 4
7 6 5

#include <bits/stdc++.h>

using namespace std;
const int maxn = 110;

int a[maxn][maxn];
int main()
{
    int tot = 1;
    int n,m,x,y;
    memset(a,0,sizeof(int));

    scanf("%d%d",&n,&m);
    x = 0;
    y = 0;
    a[0][0] = 1;
    while(tot < n*m)
    {
        while(y < m-1 && !a[x][y+1]) a[x][++y] = ++tot;
        while(x < n-1 && !a[x+1][y]) a[++x][y] = ++tot;
        while(y > 0 && !a[x][y-1]) a[x][--y] = ++tot;
        while(x > 0 && !a[x-1][y]) a[--x][y] = ++tot;
    }

    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
            printf("%d ",a[i][j]);
        putchar('\n');
    }

    return 0;
}

竖式问题

找出所有形如 abc * de(三位数乘以两位数)的算式,使得在完整的竖式中,所有数字都属于一个特定的数字集合。输入数字集合(相邻数字之间没有空格),输出所有竖式。每个竖式前应有编号,之后应有一个空行。最后输出解的总数。具体格式见样例输出(空格显示成点)。
样例输入:2357
在这里插入图片描述
书里从111和11开始,是否该从100和10开始?
了解思路即可。

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int cou = 0;
    char s[12];
    char buf[30];
    scanf("%s",s);

    for(int abc = 111; abc <= 999; abc++)
    {
        for(int de = 11; de <= 99 ; de++)
        {
            int x = abc*(de%10), y = abc*(de/10), z = abc*de;
            sprintf(buf,"%d%d%d%d%d",abc,de,x,y,z);

            int ok = 1;
            for(int i = 0; i < strlen(buf) ; i++)
                if(strchr(s,buf[i]) == NULL)
                {
                    ok = 0;
                    break;
                }
            if(ok)
            {
                printf("<%d>\n",++cou);
                printf("%5d\nX%4d\n-----\n%5d\n%4d\n-----\n%5d\n",abc,de,x,y,z);
            }
            else
                continue;
        }
    }
    printf("The number of solutions = %d\n",cou);
    return 0;
}

TeX中的引号(uva272)

原题链接:https://vjudge.net/problem/UVA-272
TEX is a typesetting language developed by Donald Knuth. It takes source text together with a few
typesetting instructions and produces, one hopes, a beautiful document. Beautiful documents use “
and ” to delimit quotations, rather than the mundane " which is what is provided by most keyboards.
Keyboards typically do not have an oriented double-quote, but they do have a left-single-quote and a right-single-quote '. Check your keyboard now to locate the left-single-quote key (sometimes
called the “backquote key”) and the right-single-quote key ’ (sometimes called the “apostrophe” or
just “quote”). Be careful not to confuse the left-single-quote ` with the “backslash” key . TEX lets
the user type two left-single-quotes to create a left-double-quote “ and two right-single-quotes '' to create a right-double-quote ”. Most typists, however, are accustomed to delimiting their quotations with the un-oriented double-quote ". If the source contained "To be or not to be," quoth the bard, "that is the question." then the typeset document produced by TEX would not contain the desired form: “To be or not to be,” quoth the bard, “that is the question.” In order to produce the desired form, the source file must contain the sequence:To be or not to be,’’ quoth the bard, that is the question.'' You are to write a program which converts text containing double-quote (") characters into text that is identical except that double-quotes have been replaced by the two-character sequences required by TEX for delimiting quotations with oriented double-quotes. The double-quote (") characters should be replaced appropriately by either if the " opens a quotation and by ‘’ if the " closes a quotation.
Notice that the question of nested quotations does not arise: The first " must be replaced by , the next by '', the next by, the next by ‘’, the next by ``, the next by ‘’, and so on.

Input
Input will consist of several lines of text containing an even number of double-quote (") characters.
Input is ended with an end-of-file character.
Output
The text must be output exactly as it was input except that:
• the first " in each pair is replaced by two ` characters: `` and
• the second " in each pair is replaced by two ’ characters: ‘’.

Sample Input
“To be or not to be,” quoth the Bard, “that
is the question”.
The programming contestant replied: “I must disagree.
To C' or not toC’, that is The Question!”

Sample Output
To be or not to be,'' quoth the Bard,that
is the question’’.
The programming contestant replied: ``I must disagree.
To C' or not toC’, that is The Question!’’

#include <bits/stdc++.h>

using namespace std;

int main()
{
   char c;
   int q = 1;

   while((c = getchar()) != EOF)
   {
       if(c == '"')
         { printf("%s",q?"``":"''"); q = !q; }
       else
        printf("%c",c);
   }

   return 0;
}

WERTYU(uva10082)

原题链接:https://vjudge.net/problem/UVA-10082
在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

int main()
{
    char s[] = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";
    char c;

    while( (c = getchar() ) != EOF)
    {
        if(!isspace(c))
        {
            char *p = strchr(s,c);
            printf("%c",*(p-1));
        }
        else
            printf("%c",c);
    }

    return 0;
}

回文词(uva401)
原题链接:https://vjudge.net/problem/UVA-401
在这里插入图片描述
在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

const char *rev = "A   3  HIL JM O   2TUVWXY51SE Z  8 ";
const char *msg[] = {"is not a palindrome.","is a regular palindrome.","is a mirrored string.","is a mirrored palindrome."};


char Reveser(char ch)
{
    if(isalpha(ch)) return rev[ch-'A'];
    return rev[ch-'0'+25];
}

int main()
{
    char str[30];

    while(scanf("%s",str) != EOF)
    {
        int len = strlen(str);
        int  p = 1, m = 1;
        for(int i = 0; i < (len+1)/2; i++)  //注意要len+1因为镜像还要判断中间字符的翻转
        {
            if(str[i] != str[len-i-1]) p = 0;
            if(Reveser(str[i]) != str[len-i-1]) m = 0;
        }
        printf("%s -- %s\n\n",str,msg[m*2+p]);
    }

    return 0;
}

猜数字游戏的提示(uva340)

原题链接:https://vjudge.net/problem/UVA-340
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
题意:
规定序列长度,第一个序列是密码,后面几个序列都是猜测,输出每个猜测中(A,B)
A情况:猜测中数字与位置都与密码中相同的总数
B情况:猜测中数字与密码中相同但位置不同的总数。

#include <bits/stdc++.h>

using namespace std;
const int maxn = 1010;
int a[maxn],b[maxn];


//情况A:数相同且位置相同的总数
//情况B:数相同但位置不同的总数
int main()
{
    int n;
    int i;
    int kase = 0;

    while(scanf("%d",&n) && n)
    {
        int c1,c2,A,B;
        A = B = c1 = c2 = 0;
        printf("Game %d:\n",++kase);
        for(i = 0; i < n; i++)
            scanf("%d",&a[i]);
        for(;;)
        {
            A = B = 0;
            for(i = 0; i < n; i++)
            {
                scanf("%d",&b[i]);
                if(a[i] == b[i])
                    A++;
            }
            if(b[0] == 0)
                break;
            for(i = 1; i <= 9; i++)
            {
                c1 = c2 = 0;
                for(int j = 0; j < n; j++)  //统计a和b序列中1~9的个数求出B情况
                {
                    if(a[j] == i) c1++;
                    if(b[j] == i) c2++;
                }
                if(c1 < c2) B += c1;
                else B += c2;
            }
            printf("    (%d,%d)\n",A,B-A);
        }
    }

    return 0;
}

生成元(uva1583)

在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;
const int maxn = 100010;
int ans[maxn];

int main()
{
    //立表
    for(int i = 1; i < maxn ; i++)
    {
        int x = i, y = i;
        while(x!=0){y += x%10; x /= 10;}
        if(ans[y] == 0 || ans[y] > i) ans[y] = i;
    }

   int T;
   scanf("%d",&T);

   while(T--)
   {
       int n;
       scanf("%d",&n);
       printf("%d\n",ans[n]);
   }

   return 0;
}

环状序列(uva1584)

原题链接:https://vjudge.net/problem/UVA-1584
在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

int Less(const char *s,int p,int q)
{
    int n = strlen(s);
    for(int i = 0; i < n; i++)
        if(s[(i+p)%n] != s[(i+q)%n])
            return s[(i+p)%n] < s[(i+q)%n];
    return 0;
}

int main()
{
    int T;
    char s[110];
    scanf("%d",&T);

    while(T--)
    {
        scanf("%s",s);
        int n = strlen(s);
        int ans = 0;
        for(int i = 1; i < n; i++)
            if(Less(s,i,ans) == 1)
              ans = i;
        for(int i = 0; i < n; i++)
            putchar(s[(i+ans)%n]);
        putchar('\n');
    }

    return 0;
}

得分(uva1585)

原题链接:https://vjudge.net/problem/UVA-1585
在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

int main()
{
    char str[90];
    int T;
    scanf("%d",&T);

    while(T--)
    {
        scanf("%s",str);
        int sum = 0, now = 0, len = strlen(str);
        for(int i = 0; i < len; i++)
        {
            if(str[i] == 'O')
                sum += ++now;
            else
                now = 0;
        }
        printf("%d\n",sum);
    }

    return 0;
}

分子量(uva1586)

在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

double mol[4] = {12.01,1.008,16.00,14.01};

int main()
{
   char str[90];
   int T;
   scanf("%d",&T);

   while(T--)
   {
       scanf("%s",str);
       int len = strlen(str);
       double sum = 0;
       for(int i = 0; i < len; i++)
       {
           if(!isdigit(str[i]))
           {
               int j = 1,x = 0;
               while(i+j < len && isdigit(str[i+j]))
               {
                   x = x*10;
                   x += str[i+j]-'0';
                   j++;
               }
               if(x == 0)
                 x = 1;
               if(str[i] == 'C')
                  sum += x*mol[0];
               else if(str[i] == 'H')
                 sum += x*mol[1];
               else if(str[i] == 'O')
                 sum += x*mol[2];
               else
                sum += x*mol[3];

                i = i+j-1;
           }
       }
       printf("%.3lf\n",sum);
   }

   return 0;
}

数数字(uva1225)

原题链接:https://vjudge.net/problem/UVA-1225
在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int n,T;
    int c[10];
    scanf("%d",&T);

    while(T--)
    {
        scanf("%d",&n);
        memset(c,0,sizeof(c));

        for(int i = 1; i <= n; i++)
        {
            int x = i;
            while(x)
            {
                c[x%10]++;
                x /= 10;
            }
        }

        for(int i = 0; i < 10 ; i++)
            {
                printf("%d",c[i]);
                if(i!=9)
                    putchar(' ');
            }
        putchar('\n');
    }

    return 0;
}

周期串(uva455)

原题链接:https://vjudge.net/problem/UVA-455
在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int T;
    char str[90];
    scanf("%d",&T);

    while(T--)
    {
        int t = 1;
        scanf("%s",str);
        int len = strlen(str);
        while(1)
        {
            int i;
            for(i = 0; i < len; i++)
                if(str[i] != str[(i+t)%len])
                  break;
            if(i == len)
                break;
            t++;
        }
        printf("%d\n",t);
        if(T!=0)
            printf("\n");
    }

    return 0;
}

谜题(uva227)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这题需要注意格式问题:最后一个答案后是没有换行符的,其他答案后面带一个换行符。
在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

int dir[4][2] = { {-1,0},{1,0},{0,-1},{0,1} }; // ABLR

int main()
{
   char c;
   char a[6][6];
   int kase = 0;
   while( (c = getchar()) && c != 'Z')
   {
       int flag = 1;
       int i,j;
       a[0][0] = c;
       int x = 0,y = 0;
       for(i = 0; i < 5; i++)
       {
           int f = 1;
           if(i == 0) j = 1;
           else j = 0;
           for(; j < 5; j++)
             {
                 c = getchar();
                 if(c == ' '){x = i; y = j; a[i][j] = ' '; }
                 else
                    a[i][j] = c;
             }
            getchar(); //吃掉回车
       }
      /* printf("34%c 40%c %d %d\n",a[3][4],a[4][0],x,y);
       //test
       for(i = 0; i < 5; i++)
           {
               for(j = 0; j < 5; j++)
               {
                   putchar(a[i][j]);
                   if(j != 4)
                     putchar(' ');
               }
               putchar('\n');
           }
       */
       while( (c = getchar()) != '0' )
       {
           int xx,yy;
           if(flag && c == 'A')
           {
               xx = x+dir[0][0];
               yy = y+dir[0][1];
               if(xx >= 0 && xx < 5 && yy >=0 && yy < 5)
               {
                   swap(a[xx][yy],a[x][y]);
                   x = xx;
                   y = yy;
               }
               else
                flag = 0;
           }
           else if(flag && c == 'B')
            {
               xx = x+dir[1][0];
               yy = y+dir[1][1];
               if(xx >= 0 && xx < 5 && yy >=0 && yy < 5)
               {
                   swap(a[xx][yy],a[x][y]);
                   x = xx;
                   y = yy;
               }
               else
                flag = 0;
           }
           else if(flag && c == 'L')
            {
               xx = x+dir[2][0];
               yy = y+dir[2][1];
               if(xx >= 0 && xx < 5 && yy >=0 && yy < 5)
               {
                   swap(a[xx][yy],a[x][y]);
                   x = xx;
                   y = yy;
               }
               else
                flag = 0;
           }
           else if(flag && c == 'R')
            {
               xx = x+dir[3][0];
               yy = y+dir[3][1];
               if(xx >= 0 && xx < 5 && yy >=0 && yy < 5)
               {
                   swap(a[xx][yy],a[x][y]);
                   x = xx;
                   y = yy;
               }
               else
                flag = 0;
           }
       }
       getchar(); //吃掉回车

       if(++kase != 1)
        putchar('\n');

       printf("Puzzle #%d:\n",kase);
       if(flag)
       {
           for(i = 0; i < 5; i++)
           {
               for(j = 0; j < 5; j++)
               {
                   putchar(a[i][j]);
                   if(j != 4)
                     putchar(' ');
               }
               putchar('\n');
           }
       }
       else
        printf("This puzzle has no final configuration.\n");
   }

   return 0;
}

纵横字谜的答案(uva232)

原题链接:https://vjudge.net/problem/UVA-232
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

int main()
{
   int r,c;
   char a[12][12];
   int num[12][12];
   int kase = 0;

   while(scanf("%d",&r) && r)
   {
       memset(num,0,sizeof(num));
       scanf("%d",&c);
       int c1 = 0;
       getchar();
       for(int i = 0; i < r; i++)
       {
           for(int j = 0; j < c; j++)
           {
               a[i][j] = getchar();
               if(a[i][j] != '*' && ( (j >0 && a[i][j-1] == '*') || j==0 || i==0 || (i > 0 && a[i-1][j] == '*')) )
                num[i][j] = ++c1;

           }
           getchar();
       }

       /*test
       for(int i = 0; i < r; i++)
       {
           for(int j = 0; j < c; j++)
            printf("%c%d ",a[i][j],num[i][j]);
           putchar('\n');
       }*/

       if(++kase != 1)
         putchar('\n');
       printf("puzzle #%d:\n",kase);
       printf("Across\n");

       for(int i = 0;i < r; i++)
       {
           for(int j = 0; j < c; j++)
           {
               if( a[i][j] != '*' && (j == 0 || a[i][j-1] == '*'))
               {
                   printf("%3d.",num[i][j]);
                   int k;
                   for(k = j; k < c; k++)
                   {
                       if(a[i][k] == '*')
                         break;
                       printf("%c",a[i][k]);
                   }
                   putchar('\n');
                   j += (k-j-1);
               }
           }
       }

       printf("Down\n");
       for(int i = 0; i < r; i++)
       {
           for(int j = 0; j < c; j++)
           {
               if(a[i][j]!='*' && (i == 0  ||  a[i-1][j] == '*' ) )
               {
                   printf("%3d.",num[i][j]);
                   int k;
                   for(k = i; k < r; k++)
                   {
                       if(a[k][j] == '*')
                        break;
                       printf("%c",a[k][j]);
                   }
                   putchar('\n');
               }
           }
       }
   }

   return 0;
}

DNA序列(uva1368)

原题链接:https://vjudge.net/problem/UVA-1368
在这里插入图片描述
在这里插入图片描述
找出每列出现次数最多dna序列即可(最小字典序)

#include <bits/stdc++.h>
#define INF 1<<31;
using namespace std;
int des[4] = {'A','C','G','T'}; //最小字典序
int main()
{
    int T,m,n;
    char a[55][1010];
    scanf("%d",&T);

    while(T--)
    {
        scanf("%d%d",&m,&n);
        for(int i = 0; i < m; i++)
            scanf("%s",a[i]);

        int sum = 0;
        char s[1010];
        int dess[97] = {0};
        for(int i = 0; i < n; i++)
        {
            int mx = 0, mc = 0;
            for(int j = 0; j < m; j++)
            {
                dess[a[j][i]]++;
            }
            for(int j = 0; j < 4; j++)
                if(mx < dess[des[j]])
                {
                    mx = dess[des[j]];
                    mc = des[j];
                }
            for(int j = 0; j < 4; j++)
                dess[des[j]] = 0;
            sum += m-mx;
            s[i] = mc;
        }
        s[n] = '\0';
        printf("%s\n",s);
        printf("%d\n",sum);
    }

    return 0;
}

循环小数(uva202)

原题链接:https://vjudge.net/problem/UVA-202
在这里插入图片描述
在这里插入图片描述
模拟笔算小数,出现循环即余数出现第二次。

#include <bits/stdc++.h>
//模拟笔算除法
//判断循坏:再次出现相同的余数

const int maxn = 3010;
using namespace std;

int cnt[maxn];
int ans[maxn];

int main()
{
    int a,b;
    int tot;
    while(~scanf("%d%d",&a,&b))
    {
        memset(cnt,0,sizeof(cnt));
        memset(ans,0,sizeof(ans));
        int c = a%b;
        tot = 0;
        printf("%d/%d = %d.",a,b,a/b);

        while(cnt[c] == 0)  //防止重复
        {
            tot++;  //先++因为0可以持续循坏
            cnt[c] = tot;  //记录位置
            ans[tot] = c*10/b;
            c = c*10%b;
        }

        for(int i = 1; i < cnt[c]; i++)
            printf("%d",ans[i]);
       if(tot-cnt[c]+1 <= 50)
        {
            printf("(");
        for(int i = cnt[c]; i <= tot; i++)
            printf("%d",ans[i]);
        printf(")\n");
        }
        else
        {
            printf("(");
            for(int i = 0,j = cnt[c]; i < 50; i++)
                printf("%d",ans[j+i]);
            printf("...)\n");
        }
        printf("   %d = number of digits in repeating cycle\n\n",tot-cnt[c]+1);
    }

    return 0;
}

子序列(uva10340)

原题链接:https://vjudge.net/problem/UVA-10340
在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

int main()
{
    string s,t;

    while(cin >> s >> t)
    {
        int lenS = s.length();
        int lenT = t.length();


        int index = 0;
        for(int i = 0; i < lenT; i++)
        {
            if(t[i] == s[index]) index++;
        }

        printf("%s\n",index == lenS ? "Yes":"No");
    }

    return 0;
}

盒子(uva1587)

在这里插入图片描述
长方形每对面中两条边都会其他两对面中的一条边相等
将每一面(由于有两面相同故只用考虑三个面)优先按短边排序相同情况按长边排序
1:第一对的最短边必然等于第二对的最短边 2:第二对的最长边必然等于第三对最长边
1:按first长短排序,第一对的first和第二对的first必然是重合的边
2:在1.2对first相同的情况下,第二对second比第一对的second长,故第二对second与第三对second是重合的边

#include <bits/stdc++.h>

using namespace std;

pair<int,int> p[3];

//长方形每对面中两条边都会其他两对面中的一条边相等
int check()  //1:第一对的最短边必然等于第二对的最短边 2:第二对的最长边必然等于第三对最长边(前提条件优先按短边排序相同情况按长边排序)
{
   return p[0].first == p[1].first && p[0].second == p[2].first && p[1].second == p[2].second;
}

1:按first长短排序,第一对的first和第二对的first必然是重合的边
2:在1.2对first相同的情况下,第二对second比第一对的second长,故第二对second与第三对second是重合的边

int main()
{
    int w[6],h[6];

    while(~scanf("%d%d",&w[0],&h[0]))
    {
        for(int i = 1; i < 6; i++)
            scanf("%d%d",&w[i],&h[i]);
        char buf[6][30];
        for(int i = 0; i < 6; i++)
            {
                if(w[i] < h[i])
                 sprintf(buf[i],"%d %d",w[i],h[i]);
                else
                  sprintf(buf[i],"%d %d",h[i],w[i]);
            }

        int cnt = 0;
        int vis[6] = {0};   //找到一对后将其标记
        for(int i = 0; i < 6; i++)
        {
            if(!vis[i])
            for(int j = 0; j < 6; j++)
            {
                if(i == j || vis[j])
                  continue;
                if(strcmp(buf[i],buf[j]) == 0)
                {
                    if(h[i] > w[i])
                    {
                      p[cnt].first = w[i];
                      p[cnt].second = h[i];
                    }
                    else
                    {
                        p[cnt].first = h[i];
                        p[cnt].second = w[i];
                    }
                    vis[i] = vis[j] = 1;
                    cnt++;
                    break;
                }
            }
        }
        if(cnt == 3)
         {
             sort(p,p+3);
             /*test
             for(int i = 0; i < 3; i++)
                printf("%d %d\n",p[i].first,p[i].second);
            */
         }

        if(cnt == 3 && check())
             printf("POSSIBLE\n");
        else
            printf("IMPOSSIBLE\n");
    }

    return 0;
}

换低档配置(uva1588)

在这里插入图片描述
在这里插入图片描述
只要注意翻转一下两串,底变为上,上变为底,再匹配一次就行(翻转会有新的结果)

#include <bits/stdc++.h>
#define local
using namespace std;
const int maxn = 110;

int main()
{
    char t[maxn],s[maxn];

    #ifdef local
    freopen("data.in","r",stdin);
    #endif // local

    while(~scanf("%s%s",t,s))
    {
        int len1 = strlen(t);
        int len2 = strlen(s);
        int ans = len1+len2;
        for(int i = 0; i < len1; i++)
        {
            int l = 0,j;
            for(j = 0; j < len2; j++)
            {
                if(i+j > len1-1)
                    l++;
                else if(t[i+j] + s[j] - 2*'0' != 4)
                  {
                      continue;
                  }
                else
                    break;
            }
            if(j == len2){
                ans = min(ans,len1+l);
                break;
            }
        }

        //翻转再匹配一次
        for(int i = 0; i < len2; i++)
        {
            int l = 0,j;
            for(j = 0; j < len1; j++)
            {
                if(i+j > len2-1)
                    l++;
                else if(s[i+j] + t[j] - 2*'0' !=4)
                    continue;
                else
                    break;
            }
            if(j == len1)
            {
                ans = min(ans,len2+l);
                break;
            }
        }


        printf("%d\n",ans);
    }

    return 0;
}

浮点数(uva11809)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <bits/stdc++.h>

//浮点数的相等要fabs(a-b)< 1e-4
using namespace std;

int main()
{
    double A;
    int B;
    double ansf[10][31];
    int ansi[10][31];

    //打表
    for(int i = 0; i <= 9 ; i++)  //尾数M
    {
        double m = 1-pow(2,-i-1);
        for(int j = 1; j <= 30; j++) //阶码E
        {
            int e = pow(2,j)-1;
            double t = log10(m)+e*log10(2);
            ansi[i][j] = t;
            ansf[i][j] = pow(10,t-ansi[i][j]);
        }
    }

    string in;
    while(cin >> in && in != "0e0")
    {
        for(string::iterator i = in.begin(); i != in.end(); ++i)
            if(*i == 'e')
             *i = ' ';
        istringstream ss(in);
        ss >> A >> B;
        for(int i = 0; i <= 9; i++) //阶码M
        {
          int flag = 0;
         for(int j = 1; j <= 30; j++) //尾数E
          {
            if(B == ansi[i][j]  && fabs(A-ansf[i][j]) < 1e-4)
            {
                printf("%d %d\n",i,j);
                flag = 1;
                break;
            }
          }
          if(flag)
            break;
        }
    }
    return 0;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值