https://ac.nowcoder.com/acm/contest/14383/K
暴力是天,剪枝就是垃圾
nju1半小时过,我一算复杂度T*14*14*34*34=2e9?然后加了一车剪枝
赛后发现加完剪枝跟暴力跑得一样快
nju1的还是用dfs,没用贪心去搞,更快
我考虑了对 找听牌时 cnt_w cnt_s cnt_b cnt_z 必须%3是0 0 0 1或者0 0 2 2这样才有可能摸一张牌得到可行解
然后找雀头时 要么cnt_zi %3=0,cnt_zi%2=2时必选zi作quetou
草了,不然能早两个小时过,C题就有机会写了
上面这份纯暴力,下面那份加剪枝
#include<bits/stdc++.h>
using namespace std;
const int maxl=1010;
int anscnt;
struct tile
{
int id,val;
}b[maxl];
int a[5][maxl],len[5];
int ta[5][maxl];
vector<tile> ans[5][maxl];
char s[maxl],c[5];
inline bool cmp(const tile &a,const tile &b)
{
if(a.id==b.id)
return a.val<b.val;
return a.id<b.id;
}
inline void prework()
{
len[1]=len[2]=len[3]=9;len[4]=7;
c[1]='w';c[2]='b';c[3]='s';c[4]='z';
for(int i=1;i<=4;i++)
for(int j=1;j<=len[i];j++)
a[i][j]=0,ans[i][j].clear();
scanf("%s",s+1);
for(int i=1;i<=14;i++)
{
b[i].val=s[2*i-1]-'0';
for(int j=1;j<=4;j++)
if(c[j]==s[2*i])
b[i].id=j;
a[b[i].id][b[i].val]++;
}
sort(b+1,b+1+14,cmp);
}
inline bool ok()
{
for(int j=1;j<=len[4];j++)
if(a[4][j]%3>0)
return false;
for(int i=1;i<=3;i++)
for(int j=1;j<=len[i];j++)
ta[i][j]=a[i][j];
for(int i=1;i<=3;i++)
for(int j=1;j<=len[i];j++)
{
ta[i][j]%=3;
if(ta[i][j+1]<ta[i][j] || ta[i][j+2]<ta[i][j])
return false;
ta[i][j+1]-=ta[i][j];ta[i][j+2]-=ta[i][j];
}
return true;
}
inline bool jug()
{
bool flag=false;
for(int k=1;k<=4 && !flag;k++)
{
int l=len[k];
for(int i=1;i<=l && !flag;i++)
if(a[k][i]>=2)
{
a[k][i]-=2;
if(ok()) flag=true;
a[k][i]+=2;
}
}
return flag;
}
inline void mainwork()
{
if(jug())
{
anscnt=-1;
return;
}
b[0].id=0;
for(int i=1;i<=14;i++)
if(b[i].id!=b[i-1].id || b[i].val!=b[i-1].val)
{
a[b[i].id][b[i].val]--;
for(int k=1;k<=4;k++)
for(int j=1;j<=len[k];j++)
{
a[k][j]++;
if(jug())
ans[b[i].id][b[i].val].push_back(tile{k,j});
a[k][j]--;
}
a[b[i].id][b[i].val]++;
}
anscnt=0;
for(int i=1;i<=4;i++)
for(int j=1;j<=len[i];j++)
if((int)ans[i][j].size()>0)
anscnt++;
}
inline void print()
{
if(anscnt<0)
puts("Tsumo!");
else
{
printf("%d\n",anscnt);
for(int i=1;i<=4;i++)
for(int j=1;j<=len[i];j++)
if((int)ans[i][j].size()>0)
{
printf("%d%c ",j,c[i]);
for(tile d:ans[i][j])
printf("%d%c",d.val,c[d.id]);
puts("");
}
}
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
print();
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int maxl=1010;
int anscnt;
struct tile
{
int id,val;
}b[maxl];
int a[5][maxl],len[5],cnt[5];
int ta[5][maxl];
vector<tile> ans[5][maxl];
char s[maxl],c[5];
inline bool cmp(const tile &a,const tile &b)
{
if(a.id==b.id)
return a.val<b.val;
return a.id<b.id;
}
inline void prework()
{
len[1]=len[2]=len[3]=9;len[4]=7;
c[1]='w';c[2]='b';c[3]='s';c[4]='z';
for(int i=1;i<=4;i++)
for(int j=1;j<=len[i];j++)
a[i][j]=0,ans[i][j].clear();
scanf("%s",s+1);
for(int i=1;i<=14;i++)
{
b[i].val=s[2*i-1]-'0';
for(int j=1;j<=4;j++)
if(c[j]==s[2*i])
b[i].id=j;
a[b[i].id][b[i].val]++;
}
sort(b+1,b+1+14,cmp);
}
inline bool ok()
{
for(int j=1;j<=len[4];j++)
if(a[4][j]%3>0)
return false;
for(int i=1;i<=3;i++)
for(int j=1;j<=len[i];j++)
ta[i][j]=a[i][j];
for(int i=1;i<=3;i++)
for(int j=1;j<=len[i];j++)
{
ta[i][j]%=3;
if(ta[i][j+1]<ta[i][j] || ta[i][j+2]<ta[i][j])
return false;
ta[i][j+1]-=ta[i][j];ta[i][j+2]-=ta[i][j];
}
return true;
}
inline bool jug(int k,int j)
{
bool flag=false;
if(cnt[4]%3==2)
{
if(k==4 && a[4][j]%3==2)
{
a[4][j]-=2;
if(ok()) flag=true;
a[4][j]+=2;
}
for(int j=1;j<=len[4] && !flag;j++)
if(a[4][j]%3==2)
{
a[4][j]-=2;
if(ok()) flag=true;
a[4][j]+=2;
}
}
else
{
if(cnt[4]%3!=0)
return false;
if(k>=1 && k<=3 && a[k][j]>=2)
{
a[k][j]-=2;
if(ok()) flag=true;
a[k][j]+=2;
}
for(int ii=1;ii<=14 && !flag;ii++)
{
if(b[ii].id==4)
break;
if(a[b[ii].id][b[ii].val]>=2)
{
a[b[ii].id][b[ii].val]-=2;
if(ok())
flag=true;
a[b[ii].id][b[ii].val]+=2;
}
}
}
return flag;
}
inline bool possible()
{
int cnt0=0,cnt1=0,cnt2=0;
for(int k=1;k<=4;k++)
if(cnt[k]==0) cnt0++;
else if(cnt[k]==1) cnt1++;
else cnt2++;
if(cnt0==3 && cnt1==1)
return true;
if(cnt0==2 && cnt2==2)
return true;
return false;
}
inline void mainwork()
{
for(int k=1;k<=4;k++)
cnt[k]=0;
for(int j=1;j<=14;j++)
cnt[b[j].id]=(cnt[b[j].id]+1)%3;
if(jug(0,0))
{
anscnt=-1;
return;
}
b[0].id=0;
for(int i=1;i<=14;i++)
if(b[i].id!=b[i-1].id || b[i].val!=b[i-1].val)
{
a[b[i].id][b[i].val]--;
for(int k=1;k<=4;k++)
cnt[k]=0;
for(int j=1;j<=14;j++)
if(i!=j)
cnt[b[j].id]=(cnt[b[j].id]+1)%3;
if(possible())
{
for(int k=1;k<=4;k++)
if(cnt[k]>0)
for(int j=1;j<=len[k];j++)
{
a[k][j]++;
int tmp=cnt[k];cnt[k]=(cnt[k]+1)%3;
if(jug(k,j))
ans[b[i].id][b[i].val].push_back(tile{k,j});
a[k][j]--;cnt[k]=tmp;
}
}
a[b[i].id][b[i].val]++;
}
anscnt=0;
for(int i=1;i<=4;i++)
for(int j=1;j<=len[i];j++)
if((int)ans[i][j].size()>0)
anscnt++;
}
inline void print()
{
if(anscnt<0)
puts("Tsumo!");
else
{
printf("%d\n",anscnt);
for(int i=1;i<=4;i++)
for(int j=1;j<=len[i];j++)
if((int)ans[i][j].size()>0)
{
printf("%d%c ",j,c[i]);
for(tile d:ans[i][j])
printf("%d%c",d.val,c[d.id]);
puts("");
}
}
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
print();
}
return 0;
}