#26371: c++ 額外測資跟解題想法


qawl987 (中央地板好滑)

學校 : 不指定學校
編號 : 149523
來源 : [140.115.50.44]
最後登入時間 :
2021-10-05 20:06:04
a291. nAnB problem | From: [1.161.126.145] | 發表日期 : 2021-08-03 20:46

 

提供一下額外測資上面的是另外一則討論的(感謝感謝),倒數二跟三是經過line9008,line9809慘痛教訓得到,最後一個是一位大師回覆的感謝。

1 2 3 4

1

0 1 1 1

0A1B

1 1 1 2

1

0 0 0 1

0A1B

1 1 2 2

1

2 2 1 1

2A2B

8 1 1 8

1

1 1 0 1

1A1B

8 8 1 1

1

1 1 0 1

1A1B

1 2 3 2

1

2 3 1 1

0A3B

因為我很爛寫了三個版本(其實有看到很多很快的寫法,字元代換等),最後的想法是:

將測資嘗試的部分(非密碼)四個位置用布林陣列代表有沒有對應過密碼了。

每次如果有B或A出現就改變該布林陣列值,然後用另一個布林代表這輪已經有B了,使迴圈繼續尋找A,但不再新增B。

這樣做有好處就是可以避免倒數二三的那種機車測資。

如果迴圈找到A就把前面存起來的B_index給改回去。

 

當如果某數字對到A但該位置已有B了,就讓迴圈繼續下去再找一個B替代;反之如果對到A但沒B直接break就好。

最後根據布林陣列輸出B就好。

#include <bits/stdc++.h>

using namespace std;

int main()

{

    ios_base::sync_with_stdio(false);

    cin.tie(0);

    string num;

    char c[4];

    char d[4];

    while(cin>>c[0]>>c[1]>>c[2]>>c[3])

    {

        num="";

        for(int i=0;i<4;i++)num = num+c[i];

        int time;

        cin>>time;

        while(time--)

        {

            int a=0,b=0;

            int rec;

            bool index_A[4] = {true,true,true,true};

            bool index_B[4] = {false,false,false,false};

            bool isfirst_round = true;

            int cnt=0;

            string ans="";

            cin>>d[0]>>d[1]>>d[2]>>d[3];

            for(int i=0;i<4;i++)ans = ans+d[i];

            for(int i=0;i<4;i++)

            {

                rec =-1;

                isfirst_round =true;

                for(int j=0;j<4;j++)

                {

                    if(index_A[j] == false)continue;//若這格已A跳過

                    if(num[i] == ans[j] && i==j)

                    {

                        if(index_B[j] == true)

                        {

                            a++;

                            index_A[j] = false;

                            index_B[j] = false;

                            if(rec!=-1)index_B[rec]=false;

                        }

                        else

                        {

                            a++;

                            index_A[j] = false;

                            index_B[j] = false;

                            if(rec!=-1)index_B[rec]=false;

                            break;

                        }

                    }

                    else if(num[i] == ans[j] && i!=j && index_B[j]==false && isfirst_round==true)

                    {

                        isfirst_round =false;

                        index_B[j]=true;

                        rec = j;

                    }

                }

            }

            for(int i=0;i<4;i++){if(index_B[i]==true)b++;}

            cout<<a<<'A'<<b<<'B'<<'\n';

        }

    }

 

}

 

 
#30999: Re: c++ 額外測資跟解題想法


jddlake@gmail.com (En-en smalley)

學校 : 不指定學校
編號 : 167396
來源 : [101.136.181.196]
最後登入時間 :
2023-02-15 00:08:53
a291. nAnB problem | From: [101.136.247.131] | 發表日期 : 2022-07-01 20:07

 

提供一下額外測資上面的是另外一則討論的(感謝感謝),倒數二跟三是經過line9008,line9809慘痛教訓得到,最後一個是一位大師回覆的感謝。

1 2 3 4

1

0 1 1 1

0A1B

1 1 1 2

1

0 0 0 1

0A1B

1 1 2 2

1

2 2 1 1

2A2B

8 1 1 8

1

1 1 0 1

1A1B

8 8 1 1

1

1 1 0 1

1A1B

1 2 3 2

1

2 3 1 1

0A3B

因為我很爛寫了三個版本(其實有看到很多很快的寫法,字元代換等),最後的想法是:

將測資嘗試的部分(非密碼)四個位置用布林陣列代表有沒有對應過密碼了。

每次如果有B或A出現就改變該布林陣列值,然後用另一個布林代表這輪已經有B了,使迴圈繼續尋找A,但不再新增B。

這樣做有好處就是可以避免倒數二三的那種機車測資。

如果迴圈找到A就把前面存起來的B_index給改回去。

 

當如果某數字對到A但該位置已有B了,就讓迴圈繼續下去再找一個B替代;反之如果對到A但沒B直接break就好。

最後根據布林陣列輸出B就好。

#include

using namespace std;

int main()

{

    ios_base::sync_with_stdio(false);

    cin.tie(0);

    string num;

    char c[4];

    char d[4];

    while(cin>>c[0]>>c[1]>>c[2]>>c[3])

    {

        num="";

        for(int i=0;i<4;i++)num = num+c[i];

        int time;

        cin>>time;

        while(time--)

        {

            int a=0,b=0;

            int rec;

            bool index_A[4] = {true,true,true,true};

            bool index_B[4] = {false,false,false,false};

            bool isfirst_round = true;

            int cnt=0;

            string ans="";

            cin>>d[0]>>d[1]>>d[2]>>d[3];

            for(int i=0;i<4;i++)ans = ans+d[i];

            for(int i=0;i<4;i++)

            {

                rec =-1;

                isfirst_round =true;

                for(int j=0;j<4;j++)

                {

                    if(index_A[j] == false)continue;//若這格已A跳過

                    if(num[i] == ans[j] && i==j)

                    {

                        if(index_B[j] == true)

                        {

                            a++;

                            index_A[j] = false;

                            index_B[j] = false;

                            if(rec!=-1)index_B[rec]=false;

                        }

                        else

                        {

                            a++;

                            index_A[j] = false;

                            index_B[j] = false;

                            if(rec!=-1)index_B[rec]=false;

                            break;

                        }

                    }

                    else if(num[i] == ans[j] && i!=j && index_B[j]==false && isfirst_round==true)

                    {

                        isfirst_round =false;

                        index_B[j]=true;

                        rec = j;

                    }

                }

            }

            for(int i=0;i<4;i++){if(index_B[i]==true)b++;}

            cout<

        }

    }

 

}

 

問個

1 1 2 2

1

2 2 1 1

應該是0A4B?

 
ZeroJudge Forum