暴力(Cake,HDU 5355)

来源:互联网 发布:大二申请国外大学知乎 编辑:程序博客网 时间:2024/06/08 05:20

一开始看到那么多人过,AC率还那么高,所以认为应该是一道水题,所以就直接贪心,但是过不了,然后尝试用assert来debug,发现不出任何问题,然后就不会做了。

原因是:

1、这道题目的数据赛后修改过,在改之前确实是一道水题,贪心的方法是可以AC的,但是改过之后大部分AC的代码都被卡了。说句实话修改后这道题目不算太简单。

2、理论上来讲如果assert(false)被触发,判题程序应该返回RE,之前也曾经使用过这个方法来debug,但是赛后才发现会返回WA,导致我一直认为自己的思路没有问题。我想应该是判题系统的问题,以后少用这种debug方式,如果非要用而且会返回WA,可以自己写个assert函数,然后弄个死循环,用是否返回TLE来debug。


看完题解之后,大部分博客都是按着官方题解做了一遍,就是每2m个数配在一起,直到剩下(2m,4m]个数,然后暴力(带记忆化)。

自己没有想明白为什么剩下(2m,4m]个数然后暴力就一定可以得到答案,也没有看到什么博客讲解。


我只能说,很多题目,比如贪心暴力的问题,知其然比知其所以然要简单得多,如果能想明白自然是最好,但是也应该尝试去乱搞(感觉这样做可能可以AC),能够AC才是最重要的。

题目中m给得那么小,理应从这些不和谐的数据范围中观察到什么。


代码

#include<stdio.h>#include<vector>#include<algorithm>using namespace std;typedef long long ll;const int maxn = 50;const int maxm = 15;int n,m;vector<int>vec[maxm];vector<int>ans[maxn][maxm];int vis[maxn];int avr;bool dfs(int zu,int sum,int st){    if(zu==m+1) return true;    if(sum==avr) return dfs(zu+1,0,n);    for(int num=min(st,avr-sum);num>=1;num--) if(!vis[num])    {        vis[num]=zu;        if(dfs(zu,sum+num,num-1)) return true;        vis[num]=0;    }    return false;}void solve(){    scanf("%d %d",&n,&m);    ll tot = (1ll+n)*n/2;    if(tot%m||tot/m<n)    {        puts("NO");        return;    }    for(int i=1;i<=m;i++) vec[i].clear();    while(n>4*m)    {        for(int i=1;i<=m;i++) vec[i].push_back(n-i+1);        n-=m;        for(int i=1;i<=m;i++) vec[i].push_back(n-m+i);        n-=m;    }    for(int i=1;i<=n;i++) vis[i]=0;    avr=(1+n)*n/2/m;    if(ans[n][m].size())    {        for(int i=1;i<=n;i++)            vec[ans[n][m][i]].push_back(i);    }    else    {        dfs(1,0,n);        ans[n][m].push_back(0);        for(int i=1;i<=n;i++)        {            vec[vis[i]].push_back(i);            ans[n][m].push_back(vis[i]);        }    }    puts("YES");    for(int i=1;i<=m;i++)    {        printf("%d",vec[i].size());        for(int j=0;j<(int)vec[i].size();j++) printf(" %d",vec[i][j]);        puts("");    }}int main(){    int T;    scanf("%d",&T);    while(T--) solve();    return 0;}