题解:P11229 [CSP-J 2024] 小木棍
考场思路
打表
因为我太弱了,看到这道题一个输入对应一个固定的输出,便想到了深搜打表,因为暴力思路很简单,这里直接公布代码。
优化:因为用木棍摆出的数字中有些使用的木棍数量是一样的,便可以只枚举小的数。
当然,
洛谷10分代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int T,n;
string ans;
string mi(string x,string y){
int len=x.size();
for(int i=0;i<len;i++){
if(x[i]<y[i]) return x;
if(x[i]>y[i]) return y;
}
return x;
}
void dfs(int s,string x){
if(s>n) return ;
if(s==n){
if(ans.size()>x.size()) ans=x;//判断位数
else ans=mi(ans,x);//一位一位比较
return ;
}
dfs(s+6,x+'0');
dfs(s+2,x+'1');
dfs(s+5,x+'2');
dfs(s+4,x+'4');
dfs(s+3,x+'7');
dfs(s+7,x+'8');//枚举最小数
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin>>T;
while(T--){
cin>>n;
ans='1';
for(int i=1;i<100000;i++) ans+='1';//设为最大值
dfs(2,"1");
dfs(5,"2");
dfs(4,"4");
dfs(6,"6");
dfs(3,"7");
dfs(7,"8");
if(ans.size()==100000) cout<<"-1\n";
else cout<<ans<<"\n";
}
return 0;
}
当然,以这种代码打表
正解(找规律)
经过打表后发现,
-1
1
7
4
2
6
8
//1
10
18
22
20
28
68
88
//2
108
188
200
208
288
688
888
//3
1088
1888
2008
2088
2888
6888
8888
//4
10888
18888
20088
20888
28888
68888
88888
//5
可以发现它们每
这些数字明显是有规律的(仅限
第一个数为
第二个数为
第三个数为
第四个数为
第五个数为
第六个数为
第七个数为
于是便有了以下代码:
洛谷100分代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int T,n;
int h[105]={0,-1,1,7,4,2,6,8,10,18,22,20,28,68,88};//前14个数字打表
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin>>T;
while(T--){
cin>>n;
if(n<=14) cout<<h[n];
else{
int m=(n-1)/7+1;//求出拼出的数字有几位
n%=7;//n是第几个数
if(n==1){
cout<<"10";
for(int i=3;i<=m;i++) cout<<"8";
}
else if(n==2){
cout<<"1";
for(int i=2;i<=m;i++) cout<<"8";
}
else if(n==3){
cout<<"200";
for(int i=4;i<=m;i++) cout<<"8";
}
else if(n==4){
cout<<"20";
for(int i=3;i<=m;i++) cout<<"8";
}
else if(n==5){
cout<<"2";
for(int i=2;i<=m;i++) cout<<"8";
}
else if(n==6){
cout<<"6";
for(int i=2;i<=m;i++) cout<<"8";
}
else{
for(int i=1;i<=m;i++) cout<<"8";
}
}
cout<<"\n";
}
return 0;
}