2019/11/29 CF-1263-B PIN Codes

Codeforces Round #603 (Div. 2)

題目鏈接:http://codeforces.com/contest/1263/problem/B

題意:

        t組測試樣例(1≤t≤100),每組n個4位數的字符串(2≤n≤10),經過最少多少次變換後可以變成全部不一樣。輸出變換次數和變換後的字符串。如果有多組最佳答案,輸出任意一組。

測試樣例:

input
3
2
1234
0600
2
1337
1337
4
3139
3139
3139
3139
output
0
1234
0600
1
1337
1237
3
3139
3138
3939
6139

思路:

        要使一個四位字符串和別的完全不同,又要最小變換次數,僅僅需要改變其中一位就可以了。理論上可以改變任意一位,但我選擇改變首位或末位,這樣比較方便。

注意:

        跑給定的測試樣例時可能輸出的改變後的字符串和給定的輸出樣例不一樣。這是因爲題目並未對改變形式作出限定。不限定變了之後的字符串應該是怎麼樣的,只限定用最少變換次數變成全部不一樣就行了。

 AC代碼1:

        從數字角度出發,輸入過程中標記出現過的數,然後雙重for循環向前掃描是否有與當前數相同的數字,如果有,一直改變它直到變爲未出現過的數字,將改變後的數字繼續進行標記。因爲是字符串所以首位可以是0,當不足四位時首位補零輸出即可。

#include<bits/stdc++.h>
using namespace std;
bool vis[10000];//標記出現過的數字
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        int a[10];
        scanf("%d",&n);
        int cnt=0;
        memset(vis,0,sizeof(vis));//初始化標記數組
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            vis[a[i]]=1;
        }
        for(int i=0;i<n;i++)
            for(int j=0;j<i;j++)
                if(a[i]==a[j])
                {
                    while(vis[a[i]])
                        a[i]=(a[i]+1000)%10000;//改變數字第一位,若爲三位數,輸出時首位補零
                    vis[a[i]]=1;//標記改變後的數字
                    cnt++;
                    break;
                }
        printf("%d\n",cnt);
        for(int i=0;i<n;i++)
            printf("%04d\n",a[i]);//以4位數輸出,不足四位首位補0
    }
    return 0;
}

AC代碼2:

          運用字符串,輸入過程中標記每個字符串最後一位字符。然後雙重for循環向前掃描是否有與當前字符串相同的字符串,如果有,就將當前字符串最後一位變爲一個未被標記的字符,將用掉的字符繼續進行標記。

#include<bits/stdc++.h>
using namespace std;
bool vis[10];//標記0-9十個字符
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(vis,0,sizeof(vis));//初始化標記數組
        int n;
        scanf("%d",&n);
        char s[10][5];
        int cnt=0;
        for(int i=0;i<n;i++)
        {
            scanf("%s",s[i]);
            vis[s[i][3]-'0']=1;//標記字符串最後一位
        }
        //判斷當前是否與前面的某一個相等,前面的一定是不重複的
        for(int i=0;i<n;i++)
            for(int j=0;j<i;j++)
                if(strcmp(s[i],s[j])==0)
                    for(int k=0;k<10;k++)//若相等,則找一個未被標記的替換掉最後一位
                        if(vis[k]==0)
                        {
                            s[i][3]=k+'0';
                            vis[k]=1;//繼續標記
                            cnt++;
                            break;
                        }
        printf("%d\n",cnt);
        for(int i=0;i<n;i++)
            printf("%s\n",s[i]);
    }
    return 0;
}

        AC代碼1和2都用了雙重for循環遍歷查找是否存在相同的,增加了時間複雜度。雖然都對這道題沒有影響,但學長有更好的解法。

學長AC代碼:

By siyiyimiaozhong, contest: Codeforces Round #603 (Div. 2), problem: (B) PIN Codes

#include <bits/stdc++.h>
using namespace std;
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl '\n'
string s[20];
bool vis[20];
int n,x;
 
int main()
{
    SIS;
    int T,x;
    cin >> T;
    while(T--)
    {
        cin >> n;
        map<string,int> mp;
        for(int i=0;i<n;i++)
        {
            cin >> s[i];
            mp[s[i]]++;
        }
        int cnt=0;
        for(int i=0;i<n;i++)
        {
            if(mp[s[i]]==1) continue;
            cnt++;
            mp[s[i]]--;
            for(char j='0';j<='9';j++)
            {
                s[i][0]=j;
                if(mp[s[i]]==0) 
                {
                    mp[s[i]]++;
                    break;
                }
            }
        }
        cout << cnt << endl;
        for(int i=0;i<n;i++)
            cout << s[i] << endl;
    }
    return 0;
}

 

發佈了35 篇原創文章 · 獲贊 4 · 訪問量 3293
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章