多学习。

紫书第三章 数组和字符串

例题

开灯问题

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

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

 

简单题不做解析

复制代码
#include <bits/stdc++.h>

using namespace std;

//1表示开0,0表示关(运用异或)
int main()
{
    vector<bool> light;
    int n,k;
    cin >> n >> k;
    light.resize(n+1,false);

    for(int i = 1; i <= k; ++i){
        for(int j = 1; j <= n; ++j){
            if(j%i == 0) light[j] = !light[j];
        }
    }
    for(int i = 1; i <= n; ++i){
        if(light[i])
            cout << i << " ";
    }
    cout << endl;

    return 0;
}
复制代码

 

蛇形填数

输入一个整数n(1<=n<=100),完成蛇形填数

输入:4

输出:

10 11 12 1

9  16  13 2

8  15 14 3

7   6     5 4

复制代码
#include <bits/stdc++.h>

using namespace std;
const int maxn = 110;

int a[maxn][maxn] = {0};
int main()
{
    int tot = 0;
    int n,m;
    cin >> n;

    int x = 0,y = n;
    while(tot < n*n)
    {
        while(x < n && a[x+1][y] == 0) a[++x][y] = ++tot;
        while(y > 1 && a[x][y-1] == 0) a[x][--y] = ++tot;
        while(x > 1 && a[x-1][y] == 0) a[--x][y] = ++tot;
        while(y < n && a[x][y+1] == 0) a[x][++y] = ++tot;
    }
    for(int i = 1; i <= n; ++i){
     for(int j = 1; j <= n; ++j)
      printf("%3d ",a[i][j]);
    cout << endl;
    }

    return 0;
}
复制代码

 

竖式问题

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

 

解题思路:将五个数字拼接为一个字符串,对此字符串调用find函数,查看是否符合要求

复制代码
#include <bits/stdc++.h>

using namespace std;

int main()
{
    string need;
    cin >> need;
    int cnt = 0;
    for(int i = 100; i <= 999; ++i)
        for(int j = 10; j <= 99; ++j)
    {
        bool ok = true;
        string buf = to_string(i)+to_string(j)+to_string(i*j)+to_string(i*(j%10))+to_string(i*(j/10));
        for(int i = 0; i < buf.size(); ++i){
         if(need.find(buf[i]) == string::npos) {ok = false;break;}
        }
        if(ok){
            ++cnt;
            cout << "<" << cnt << ">" << endl;
            printf("%5d\nX%4d\n----\n%5d\n%4d\n-----\n%5d\n",i,j,i*(j%10),i*(j/10),i*j);
        }
    }
    cout << "The number of solutions =" << cnt << endl;

    return 0;
}
复制代码

 

Tex中的引号(uva272)

原题链接:https://vjudge.net/problem/UVA-272

 

 

 

 题解:左引号换``,右引号换'',简单题

复制代码
#include <bits/stdc++.h>

using namespace std;

int main()
{
   char c;
   bool left = true;
   while((c = getchar()) != EOF)
   {
       if(c == '"'){
         cout << (left?"``":"''");
         left = !left;
       }
       else
        cout << c;
   }
   return 0;
}
复制代码

 

WERTYU (uva10082)

原题链接:https://vjudge.net/problem/UVA-10082

 

 题解:预处理字符串记录键盘键位,非空格字符查找字符串,输出其前一个字符

复制代码
#include <bits/stdc++.h>

using namespace std;

int main()
{
    string s = "1234567890-=QWERTYUIOP[]\ASDFGHJKL;'ZXCVBNM,./";
    char c;
    while((c = getchar()) != EOF){
        if(!isspace(c)){
         int pos = s.find(c);
         cout << s[pos-1];
        }
        else
            cout << c;
    }

    return 0;
}
复制代码

 

回文词(uva401)

原题链接:https://vjudge.net/problem/UVA-401

 

 

 

 题解:回文的判断肯定都会,镜像就是映射一下就行

利用map的解法:

复制代码
#include <iostream>
#include <map>
using namespace std;

string c = "AEHIJLMOSTUVWXYZ12358";
string r = "A3HILJMO2TUVWXY51SEZ8";
map<char,char> rev;
const string answer[4] = {"not a palindrome","a regular palindrome","a mirrored string","a mirrored palindrome"};


char revchar(char a)
{
    if(rev.find(a) == rev.end())
        return ' ';
    return rev[a];
}

int main()
{
    string s;
    for(int i = 0; i < c.size(); ++i)
        rev[c[i]] = r[i];

    while(cin >> s)
    {
        int p = 1,m = 1;
        int len = s.size();
        for(int i = 0; i <= len/2; ++i)
        {
            if(s[i] != s[len-1-i])
            { p = 0;}
            if(revchar(s[i]) != s[len-1-i]) m = 0;
        }
        cout << s << " -- is " << answer[p+m*2] << "." << endl;
cout << endl; }
return 0; }
复制代码

仅用字符串完成映射:

复制代码
#include <iostream>
using namespace std;

string r = "A   3  HIL JM O   2TUVWXY51SE Z  8 ";
const string answer[4] = {"not a palindrome","a regular palindrome","a mirrored string","a mirrored palindrome"};


char revchar(char a)
{
    if(a >= 'A' && a <= 'Z')
        return r[a-'A'];
    return r[a-'0'+25];
}

int main()
{
    string s;

    while(cin >> s)
    {
        int p = 1,m = 1;
        int len = s.size();
        for(int i = 0; i <= len/2; ++i)
        {
            if(s[i] != s[len-1-i])
            { p = 0;}
            if(revchar(s[i]) != s[len-1-i]) m = 0;
        }
        cout << s << " -- is " << answer[p+m*2] << "." << endl;
cout << endl;
}
return 0;
}
复制代码

 java用map:

复制代码
import java.util.Scanner;
import java.util.HashMap;

public class Main{
    public static void main(String[] args){
        Scanner reader = new Scanner(System.in);
        String c = "AEHIJLMOSTUVWXYZ12358";
        String r = "A3HILJMO2TUVWXY51SEZ8";
        HashMap<Character,Character> rev = new HashMap<>();
        final String answer[] = {"not a palindrome","a regular palindrome","a mirrored string","a mirrored palindrome"};

        for(int i = 0; i < c.length(); ++i){
            rev.put(c.charAt(i),r.charAt(i));
        }
        String s;
        while(reader.hasNext())
        {
            int p = 1, m =1;
            s = reader.next();
            for(int i = 0; i <= s.length()/2; ++i){
                if(s.charAt(i) != s.charAt(s.length()-1-i)) p = 0;
                if(revChar(rev,s.charAt(i)) != s.charAt(s.length()-1-i)) m = 0;
            }
            System.out.println(s+" -- is "+answer[p+m*2]+".");
            System.out.println();
        }
    }

    public static char revChar(HashMap<Character,Character> map,char a){
        if(!map.containsKey(a))
            return ' ';
        return map.get(a);
    }
}
复制代码

 

猜数字游戏的提示(UVA 340)

原题链接:https://vjudge.net/problem/UVA-340

 

 

 

 题解:统计出猜测串和密码串位置相同数字相同的位置个数即为A,统计出猜测串中和密码串中各数字出现的次数,其最小值加入到B中,B的结果为B-A(A:位置相同数字相同的个数 B:位置不同数字相同的个数)

复制代码
#include <iostream>
#include <vector>
using namespace std;

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

    while(cin >> n && n)
    {
        kase++;
        cout << "Game " << kase << ":" << endl;
        code.resize(n);
        guess.resize(n);
        for(int i = 0; i < n; ++i)
            cin >> code[i];
        for(;;){
            int A = 0, B = 0;
            for(int i = 0; i < n; ++i)
                {
                    cin >> guess[i];
                    if(guess[i] == code[i]) A++;
                }
            if(guess[0] == 0) break;
            for(int i = 1; i <= 9; ++i){
                int c1 = 0, c2 = 0; //统计数字i在密码序列和猜测序列中出现的个数
                for(int j = 0; j < n; ++j){
                    if(guess[j] == i) c1++;
                    if(code[j] == i) c2++;
                }
                B += c1<c2?c1:c2;
            }
            printf("    (%d,%d)\n",A,B-A);
        }
    }

    return 0;
}
复制代码

 

生成元(uva1583)

 

 题解:如果每次对于数字m都去遍历m-1一次计算生成元未免太费时,可以预处理先计算出从1~100000的结果,得出生成元表

复制代码
#include <iostream>
#include <cstdio>
#define maxn 100005
using namespace std;

int ans[maxn];


int main()
{
    int t;
    scanf("%d",&t);

    for(int i = 1; i <= maxn-5; ++i){
        int result = i;
        int temp = i;
        while(temp){
            result += temp%10;
            temp /= 10;
        }
        if(!ans[result])
          ans[result] = i;  //有的数有多个生成元取小的那个
    }

    int n;
    while(t--)
    {
        cin >> n;
        cout << ans[n] << endl;
    }

    return 0;
}
复制代码

 

得分(UVA1585)

原题链接:https://vjudge.net/problem/UVA-1585

 

 题解:简单题,记录连续O,遇到X变为1即可

复制代码
#include <iostream>

using namespace std;

int main()
{
    string s;
    int T;
    cin >> T;

    while(T--)
    {
        cin >> s;
        int n = s.size();
        int ans = 0;
        int m = 1;
        for(int i = 0; i < n; ++i)
        {
            if(s[i] == 'O')
            {
                ans += m;
                m++;
            }
            else
                m = 1;
        }
        cout << ans << endl;
    }

    return 0;
}
复制代码

 

分子量(UVA1586)

原题链接:https://vjudge.net/problem/UVA-1586

 

 

 

 

复制代码
#include <iostream>
#include <cstdio>
#include <cctype>
using namespace std;

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

int main()
{
   string str;
   int T;
   scanf("%d",&T);

   while(T--)
   {
     cin >> str;
     double ans = 0.0;
     int n = str.size();
     for(int i = 0; i < n; ++i){
        if(isalpha(str[i])){
            int t = 0;
            for(int j = i+1; j < n ; ++j){
                if(!isdigit(str[j]))
                    break;
                t = t*10+(str[j]-'0');
            }
            if(t == 0)
                t = 1;
            if(str[i] == 'C')
                ans += mol[0]*t;
            else if(str[i] == 'H')
                ans += mol[1]*t;
            else if(str[i] == 'O')
                ans += mol[2]*t;
            else
                ans += mol[3]*t;
        }
     }
     printf("%.3f\n",ans);
   }

   return 0;
}
复制代码

 

数数字(UVA1225)

原题链接:https://vjudge.net/problem/UVA-1225

 

 

复制代码
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;

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

    while(T--)
    {
        cin >> n;
        memset(c,0,sizeof(c));
        for(int i = 1; i <= n; ++i){
            int t = i;
            while(t){
                c[t%10]++;
                t /= 10;
            }
        }
        for(int i = 0; i < 10; ++i)
           {
               cout << c[i];
               if(i != 9)
                 cout << " ";
           }
        cout << endl;
    }

    return 0;
}
复制代码

 

周期串(UVA455)

原题链接:https://vjudge.net/problem/UVA-445

 

 题解:若为该串周期t,则s[i] == s[i+t]并同时利用约瑟夫环即s[i] == s[(i+t)%len],故我们只要从周期1开始往前遍历即可。

复制代码
#include <iostream>

using namespace std;

int main()
{
    string s;
    int t;
    cin >> t;

    while(t--)
    {
        cin >> s;
        int n = s.size();
        int ans = 1,i;
        while(1)
        {
            for(i = 0; i < n; ++i)
                if(s[i] != s[(i+ans)%n])
                  break;
            if(i == n)
                break;
            ans++;
        }
        cout << ans << endl;
        if(t != 0)
            cout << endl;
    }
    return 0;
}
复制代码

 

谜题(UVA227)

原题链接:https://vjudge.net/problem/UVA-227

 

 

 

 

 题解:简单模拟题

复制代码
#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
   char board[5][5];
   char c;
   int kase = 0, x, y;

   while((c = getchar()) && c != 'Z')
   {
       ++kase;
       board[0][0] = c;
       if(c == ' ') x = 0,y = 0;
       for(int i = 1; i < 5; ++i)
          {
              board[0][i] = getchar();
              if(board[0][i] == ' ')
                x = 0, y = i;
          }
        getchar();
        for(int i = 1; i < 5; ++i){
            for(int j = 0; j < 5; ++j)
             {
                 board[i][j] = getchar();
                 if(board[i][j] == ' ')
                    x = i, y = j;
             }
          getchar();
        }

        /*cout << "test" << endl;
       for(int i = 0; i < 5; ++i){
        for(int j = 0; j < 5; ++j)
           putchar(board[i][j]);
        cout << endl;
       }*/
       string order;
       bool flag = true;
       while(cin >> order){
        getchar(); //take enter
        int len = order.size();
        int i;
        for(i = 0; i < len && flag; ++i){
            if(order[i] == 'A'){
                if(x-1 < 0)
                    { flag = !flag;break;}
                swap(board[x][y],board[x-1][y]);
                x -= 1;
            }
            else if(order[i] == 'B'){
                if(x+1 >= 5) { flag = !flag;break;}
                swap(board[x][y],board[x+1][y]);
                x += 1;
            }
            else if(order[i] == 'L'){
                if(y-1 < 0) { flag = !flag;break;};
                swap(board[x][y],board[x][y-1]);
                y--;
            }
            else if(order[i] == 'R'){
                if(y+1 >= 5) { flag = !flag;break;}
                swap(board[x][y],board[x][y+1]);
                y++;
            }
        }
        if(order[len-1] == '0')
            break;
       }

       if(kase != 1)
        cout << endl;

       printf("Puzzle #%d:\n",kase);
       if(flag){
           for(int i = 0; i < 5; ++i){
        for(int j = 0; j < 5; ++j)
           { cout << board[i][j] ; if(j != 4) cout << " ";}
        cout << endl;
         }
       }
       else
        cout << "This puzzle has no final configuration." << endl;
   }
}
复制代码

 

纵横字谜答案(UVA232)

 

 

 

 

 

 

复制代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int main()
{
    int r,c;
    char board[12][12];
    int num[12][12];
    int kase = 0;
    while(cin >> r && r != 0)
    {
        ++kase;
        cin >> c;
        getchar();
        memset(num,0,sizeof(num));
        for(int i = 0; i < r; ++i){
            for(int j = 0; j < c; ++j)
              board[i][j] = getchar();
            getchar();
        }
        //test
        /*for(int i = 0; i < r; ++i){
            for(int j = 0; j < c; ++j)
                cout << board[i][j] << " ";
            cout << endl;
        }*/
        int c1 = 0;
        for(int i = 0; i < r; ++i)
        {
            for(int j = 0; j < c; ++j)
            {
                if((i == 0 || j == 0 || board[i-1][j] == '*' || board[i][j-1] == '*') && board[i][j] != '*')
                    num[i][j] = ++c1;
            }
        }
        //test
        /*for(int i = 0; i < r; ++i){
            for(int j = 0; j < c; ++j)
                cout << num[i][j] << " ";
            cout << endl;
        }*/

        if(kase != 1) cout << endl;
        printf("puzzle #%d:\n",kase);
        cout << "Across" << endl;
        for(int i = 0; i < r; ++i)
            for(int j = 0; j < c; ++j)
        {
            if(num[i][j] != 0){
                printf("%3d.",num[i][j]);
                for(; j < c; ++j)
                {
                    cout << board[i][j];
                    if(j != c-1 && board[i][j+1] == '*') break;
                }
                cout << endl;
            }
        }
        cout << "Down" << endl;
        for(int i = 0; i < r; ++i)
            for(int j = 0; j < c; ++j)
        {
            if(num[i][j] != 0 && (i == 0 || board[i-1][j] == '*')){
                printf("%3d.",num[i][j]);
                for(int k = i; k < r; ++k){
                    if(board[k][j] == '*') break;
                    cout << board[k][j];
                }
                cout << endl;
            }
        }
    }

    return 0;
}
复制代码

 

 DNA序列(UVA202)

 

 

 

 

复制代码
#include <iostream>
#include <cstdio>
#include <map>
#include <cstring>
using namespace std;
int des[4] = {'A','C','G','T'};
map<char,int> dict = { {'A',0},{'C',1},{'G',2},{'T',3} };
int main()
{
    int T,m,n;
    string a[55];
    scanf("%d",&T);

    while(T--)
    {
        int cnt[4];
        int haming = 0;
        string ans;
       cin >> n >> m;
       for(int i = 0; i < n; ++i)
        cin >> a[i];
       for(int i = 0; i < m; ++i)
       {
           memset(cnt,0,sizeof(cnt));
           for(int j = 0; j < n; ++j){
             cnt[dict[a[j][i]]]++;
           }
           int mx = 0, k = 0;
           for(int  j = 0; j < 4; ++j)
            {
                if(mx < cnt[j])
                    mx = cnt[j], k = j;
            }
           haming += n-mx;
           ans += des[k];
       }
       cout << ans << endl;
       cout << haming << endl;
    }

    return 0;
}
复制代码

 

循坏小数(UVA202)

 

 题解:因为除数不会变,故出现相同的余数即是循坏小数,我们可以用两个数组

int cnt[maxn]; //记录小数第一次出现的位置
int ans[maxn]; //记录每个位置上的值

可循环判断余数:

while(cnt[c] == 0)
{
tot++;
cnt[c] = tot; //记录第一次出现的位置
ans[tot] = c*10/b; //记录位置上的数
c = c*10%b;
}

复制代码
#include <iostream>
#include <cstdio>
#include <cstring>
//模拟笔算除法
//判断循坏:再次出现相同的余数

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));
        tot = 0;
        printf("%d/%d = %d.",a,b,a/b);
        int c = a%b;

        while(cnt[c] == 0)
        {
            tot++;
            cnt[c] = tot;  //记录第一次出现的位置
            ans[tot] = c*10/b;  //记录位置上的数
            c = c*10%b;
        }

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

    return 0;
}
复制代码

 

子序列(UVA10340)

 

 

复制代码
#include <iostream>

using namespace std;

int main()
{
    string s,t;

    while(cin >> s >> t)
    {
        int sl = s.size();
        int tl = t.size();
        int index = 0;
        for(int i = 0; i < tl; ++i)
            if(t[i] == s[index]) index++;
        cout << (index == sl?"Yes":"No") << endl;
    }

    return 0;
}
复制代码

 

盒子(UVA1587)

 

 

 

 题解:

//组成盒子:前提三对相同的面(短边相同长边相同)
//拥有3对后:进行排序,其实就是 左 上 前 三个面,左的长边等于前的短边 左的短边等于上的短边 前的长边等于上的长边
//左肯定是最小的,上和前也是确定的,因为上有一条短边

c++11 to_string解法:

复制代码
#include <iostream>
#include <cstdio>
#include <string>
#include <utility>
#include <algorithm>
using namespace std;

//组成盒子:前提三对相同的面(短边相同长边相同)
//拥有3对后:进行排序,其实就是 左 上 前 三个面,左的长边等于前的短边 左的短边等于上的短边 前的长边等于上的长边
//左肯定是最小的,上和前也是确定的,因为上有一条短边

bool check(pair<int,int> p[])
{
    return p[0].first == p[1].first && p[0].second == p[2].first && p[1].second == p[2].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]);

        string buf[6];
        for(int i = 0; i < 6; ++i)
        {
            if(w[i] < h[i])
                buf[i] = to_string(w[i]) +" "+to_string(h[i]);
            else
                buf[i] = to_string(h[i]) +" "+to_string(w[i]);
            //cout << buf[i] << endl;
        }

        int cnt = 0; //记录是否有3对
        pair<int,int> p[3];
        int vis[6] = {0};  //找到三对
        for(int i = 0; i < 6; ++i)
        {
            if(!vis[i])
            for(int j = 0; j < 6; ++j)
            {
                if(j == i || vis[j]) //已用作一对
                    continue;
                if(buf[i] == buf[j])
                {
                    p[cnt].first = stoi(buf[i].substr(0,buf[i].find_first_of(" ")));
                    p[cnt].second = stoi(buf[i].substr(buf[i].find_first_of(" ")));
                    vis[i] = vis[j] = 1; //已成为1对标记
                    cnt++;
break;
                }
            }
        }
        sort(p,p+3);
        

        if(cnt == 3 && check(p))
            cout << "POSSIBLE" << endl;
        else
            cout << "IMPOSSIBLE" << endl;
    }

    return 0;
}
复制代码

c++11前:

复制代码
#include <bits/stdc++.h>

using namespace std;

pair<int,int> p[3];
//组成盒子:前提三对相同的面(短边相同长边相同)
//拥有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;
}
复制代码

 

换低档配置(UVA1587)

 

 

 

 

 

 题解:一个为底另一位顶,为底不动,顶部从底部头至尾遍历找到全程无超过3的情况。

注意:翻转会有不同结果

 

 

 

复制代码
#include <iostream>
#include <cstdio>

using namespace std;


//注意:翻转的结果不同

int main()
{

    string top,low;

    while(cin >> top >> low)
    {
        int n = top.size(), m = low.size();
        int ans = n+m;

        for(int i = 0; i < m; ++i)   //low为底
        {
            int l = 0; //用于记录超出底部的长度
            bool flag = true; //记录有无超过3限定
            for(int j = 0; j < n; ++j)
            {
                if(i+j == m)
                    {
                        l += n-j;
                        break;
                    }
                else
                {
                    if(low[i+j]+top[j]-2*'0' == 4)
                    {
                        flag = false;
                        break;
                    }
                }
            }
            if(flag)
                {
                    ans = min(ans,m+l);
                    break;
                }
        }

        for(int i = 0; i < n; ++i) //以top为底
        {
            int l = 0;
            bool flag = true;
            for(int j = 0; j < m; ++j)
            {
                if(i+j >= n)
                    {
                        l += m-j;
                        break;
                    }
                else if(top[i+j]+low[j]-2*'0' == 4)
                {
                    flag = false;
                    break;
                }
            }
            if(flag)
                {
                    ans = min(ans,n+l);
                    break;
                }
        }
        cout << ans << endl;

    }
    return 0;
}
复制代码

 

浮点数(UVA11809)

 

 

 

 题解:

 

 

复制代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <sstream>
#define ESP 1e-4
using namespace std;


int main()
{
    //M:0~9   E:1~30
    int ansi[10][31];
    double ansd[10][31];


    for(int i = 0; i <= 9; ++i) //M:0-9
    {
        for(int j = 1; j <= 30; ++j) //E:1-30
        {
            double t = log10(1-pow(2,-i-1))+(pow(2,j)-1)*log10(2);
            ansi[i][j] = (int)t;
            ansd[i][j] = pow(10,t-ansi[i][j]);  //把log10(A)转换为A
        }
    }

    string s;
    while(cin >> s)
    {
        for(auto p = s.begin(); p != s.end(); ++p)
            if(*p == 'e')
             *p = ' ';
        stringstream is(s);
        double A;
        int B;
        is >> A >> B;
        if(fabs(A-0) <= ESP && B == 0)
            break;
        bool flag = true;
        for(int i = 0; i <= 9 && flag; ++i)
          for(int j = 1; j <= 30 && flag; ++j)
        {
            if(B == ansi[i][j] && fabs(A-ansd[i][j]) <= ESP)
            {
                cout << i << " " << j << endl;
                flag = false;
            }

        }
    }

    return 0;
}
复制代码

 

posted @   czyaaa  阅读(56)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示