社区讨论
这种做法能够申请题解吗
P11229[CSP-J 2024] 小木棍参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @m2wyxpus
- 此快照首次捕获于
- 2024/10/31 15:12 去年
- 此快照最后确认于
- 2025/11/04 15:39 4 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
int t,n;
struct node{
int v=1;
int s[10]={0,0,0,0,0,0,0,0,0,0};
} ans[100005];
//ans[i] 用i个小木棒拼成的最小数,用各个数字的次数
inline int read(){
int x=0,w=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') w=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*w;
}
inline int cmp(node i,node j){
int k1=0,k2=0;
for(int k=0;k<=9;k++){
k1+=i.s[k];
k2+=j.s[k];
}
if(k1<k2) return 1;
if(k1>k2) return 3;
for(int k=1;k<=9;k++){
if(i.s[k]&&j.s[k]) break;
else if(i.s[k]){
if(!j.s[k]){
return 1;
}
}
else if(j.s[k]){
if(!i.s[k]){
return 6;
}
}
}
for(int k=0;k<=9;k++) if(i.s[k]>j.s[k]){return 1;}else if(i.s[k]<j.s[k]) return 9;
return 1;
}
signed main( ){
ans[1].v=-1;
ans[2].s[1]=1;
ans[3].s[7]=1;
ans[4].s[4]=1;
ans[5].s[2]=1;
ans[6].s[6]=1;
ans[7].s[8]=1;
ans[8].s[1]=1;
ans[8].s[0]=1;
int s[10]={0,6,2,4,5,3,7};
int ss[10]={0,0,1,4,2,7,8};
for(register int i=9;i<=100000;i++){
for(register int j=1;j<=6;j++){
int k=s[j];
node x=ans[i-k];
x.s[ss[j]]++;
if(j==1){
ans[i]=x;
continue;
}
if(cmp(ans[i],x)%3==0){
ans[i]=x;
}
}
}
t=read();
while(t--){
n=read();
int jl=0;
for(register int i=1;i<=9;i++) if(ans[n].s[i]){putchar(i+'0');jl=i;break;}
for(register int i=0;i<=9;i++){
if(i==jl){
for(register int j=1;j<ans[n].s[i];j++) putchar(i+'0');
}
else for(register int j=1;j<=ans[n].s[i];j++) putchar(i+'0');
}
if(ans[n].v==-1){
putchar('-');
putchar(1+'0');
}
putchar('\n');
}
}
freopen已经删了,并且能AC,时间复杂度也足够优,全在14ms(因为我是先预处理出所有答案,然后读入一个就输出一个)。主要为dp,类似硬币问题的做法。cmp用于比较两个ans大小,最后贪心输出
回复
共 2 条回复,欢迎继续交流。
正在加载回复...