Educational Codeforces Round 96(Rated forDiv。2)A。アパートの数(模拟+思维)

タイトルリンク: ポータル
タイトル貼り付け:
ここに画像の説明を挿入質問の意味:整数nを指定します。答えがあれば、このnをax 3 + bx 5 + cx 7 = n(a、b、c> = 0)の形式で記述できますか?種類はたくさんあり、ランダムに出力します。存在しない場合は-1を出力します。
考え:
a、b、cの範囲を大まかに計画できます(質問nは整数<= 1000であるため) 、最大aは333です。これは、1000に最も近い333x3 = 999であるため、bの最大値は200、cの最大値は142です。
暴力の3つのループ方法を試してみましょう。test5で直接試してみましたが、タイムアウトしました(以下のタイムアウト
はコードです)



    #include<bits/stdc++.h>
    namespace mySpace{
    
    
        typedef long long int ll;
        typedef long double ld;
        typedef double db;
        //typedef __int64 int bi;
        //nth_element(first,pos,end) =>STL function ,求第pos小的元素
        #define fori(a,b,c) for(int a=b;a<=c;++a)
        #define me(a) memset(a,0,sizeof a)
        #define Mod 1000000009
        #define exp 1e-8
        #define fi first
        #define se second
        #define sc_int(x) scanf("%d",&x)
        #define sc_db(x) scanf("%lf",&x)
        #define sc_str(x) scanf("%s",x)
        #define sc_bi(x) scanf("%I64d",&x)
        #define pr_int(x) printf("%d\n",x)
        #define pr_bi(x) printf("%lld\n",x)
        const int INF = 0x7fffffff;
        const int MAX1 = 2e5+10;
        const int MAX2 = 1e6+10;
        const int MAX3 = 2e6+10;
        //#define IS std::ios::sync_with_stdio(false)
        //#define OS std::cin.tie(NULL)
        void readFoler()
        {
    
    
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
        }
        void closeFoler()
        {
    
    
            fclose(stdin);
            fclose(stdout);
        }
    }
    using namespace std;
    using namespace mySpace;
     
    int main(void)
    {
    
    
        int t,n;
        sc_int(t);
        while(t--)
        {
    
    
            sc_int(n);
            int ok=0;
            int a=0,b=0,c=0;
            for(int i=0;i<=334;++i)
            {
    
    
                for(int j=0;j<=200;++j)
                {
    
    
                    for(int k=0;k<=150;++k)
                    {
    
    
                        if(i*3+j*5+k*7==n){
    
    
                            a = i;
                            b = j;
                            c = k;
                            ok = 1;
                            goto end;
                        }
                    }
                }
            }
            end:;
            if(ok) cout<<a<<" "<<b<<" "<<c<<endl;
            else cout<<"-1"<<endl;
        }
    }

結果:
ここに画像の説明を挿入
最適化:トリプルループでは不十分です。次にダブルループを使用し、最適化する方法を教えてください。
aとbを決定すると、cも決定できることがわかりました。つまり、s = n-(ax 3 + bx 5); s%7 == 0の場合、結果はOKです。2サイクル終了します。逆は不可能です。このようにして、3サイクルから2サイクルへの最適化を実現しました。

    #include<bits/stdc++.h>
    namespace mySpace{
    
    
        typedef long long int ll;
        typedef long double ld;
        typedef double db;
        //typedef __int64 int bi;
        //nth_element(first,pos,end) =>STL function ,求第pos小的元素
        #define fori(a,b,c) for(int a=b;a<=c;++a)
        #define me(a) memset(a,0,sizeof a)
        #define Mod 1000000009
        #define exp 1e-8
        #define fi first
        #define se second
        #define sc_int(x) scanf("%d",&x)
        #define sc_db(x) scanf("%lf",&x)
        #define sc_str(x) scanf("%s",x)
        #define sc_bi(x) scanf("%I64d",&x)
        #define pr_int(x) printf("%d\n",x)
        #define pr_bi(x) printf("%lld\n",x)
        const int INF = 0x7fffffff;
        const int MAX1 = 2e5+10;
        const int MAX2 = 1e6+10;
        const int MAX3 = 2e6+10;
        //#define IS std::ios::sync_with_stdio(false)
        //#define OS std::cin.tie(NULL)
        void readFoler()
        {
    
    
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
        }
        void closeFoler()
        {
    
    
            fclose(stdin);
            fclose(stdout);
        }
    }
    using namespace std;
    using namespace mySpace;
     
    int main(void)
    {
    
    
        int t,n;
        sc_int(t);
        while(t--)
        {
    
    
            sc_int(n);
            int ok=0;
            int a=0,b=0,c=0;
            for(int i=0;i<=334;++i)
            {
    
    
                for(int j=0;j<=201;++j)
                {
    
    
                    if(n-(i*3+j*5)>=0&&(n-(i*3+j*5))%7==0){
    
     //注意前面一定要要>=0!!!
                        a = i;
                        b = j;
                        c = (n-(i*3+j*5))/7;
                        ok = 1;
                        goto end; //goto 是瞬间转移到某某位置,比如这里是转移到end位置,也就相当于退出两重循环了
                    }
                }
            }
            end:;
            if(ok) cout<<a<<" "<<b<<" "<<c<<endl;
            else cout<<"-1"<<endl;
        }
    }

結果: ここに画像の説明を挿入
それでスムーズに進みました。この質問のトピックは比較的単純ですが、ループが多すぎることを知っておく必要があります。それを最適化する方法を見つける必要があります。質問をするために質問をしないでください。より良い最適化、将来的に問題を解決するためのより多くのオプションがあります!

おすすめ

転載: blog.csdn.net/YSJ367635984/article/details/109056937