タイトルリンク: ポータル
タイトル貼り付け:
質問の意味:整数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;
}
}
結果:
それでスムーズに進みました。この質問のトピックは比較的単純ですが、ループが多すぎることを知っておく必要があります。それを最適化する方法を見つける必要があります。質問をするために質問をしないでください。より良い最適化、将来的に問題を解決するためのより多くのオプションがあります!