[NOIP TG]来自一个打崩的分数比得的分数都高的蒟蒻的怨念

(dalao说标题一定要长长长长长长长长长)
(所以说觉得自己有hippopotomonstrosesquipedaliophobia的读者还是不要看这篇没什么用的blog了)

恩为什么说怨念呢,因为……这个蒟蒻……从一打完NOIP就知道自己打崩了,但是他花了5分钟就多出来120分,然后又花了30分钟把D1T2打出来了,然后……他花了10分钟把D2T3的暴力修好了,又用了5分钟把D2T2写惨的暴力修好了结果A掉了这个题= =

(所以说这个蒟蒻虽然只拿了225分但实际上本来能拿460分,真的是怨念= =)
↑但他还是个蒟蒻,因为……都高二了还把暴力打崩了、还写I64d、还不会强转long long,就是个蒟蒻,不像RTYdalao,轻轻松松打了350)

Day 1

T1

这是一个结论题啦,结论就是 a * b - a - b,还可以写成非主流的( a - 1 ) * ( b - 1 ) - 1的形式,但是需要用long long存结论否则会炸掉。打表找规律就能比较轻松的得出结论来,然后就打了I64d死透了(Die)

T2

这个没的说,模拟一下这个过程完全就可以干掉这个题,只不过细节会比较多(然后就残了)。

T3

这个题……反正我到现在都不会做,就写个暴力跑最短路然后BFS找条数,显而易见得不了多少分,最后得了30分也算不亏了

Day 2

T1

像我们机房真正的dalao啊,一看题目描述上来就是打了个点积啊什么的板子啊,我不会这个好像反而还没掉到坑里233
这个题可以选择计算球心之间的距离,如果小于等于2*r那就连一条边,最后从下表面连所有能连的球心、上表面连所有能连的球心,从下表面开始跑搜索看看能不能找到上表面就行了
不过这个范围非常的诡异啊(虽然出题人之后表明了不会炸掉long long,坐标也不存在z的值小于0的情况),x、y、z之间极限情况下会炸long long,用double也可能被卡精度,所以直接分开算平方靠减的(然后没强转long long少了20分QAQ)

T2

这个题看数据范围知状压DP,然后……这题……可以用玄妙的搜索过…………
代码放在最后面,实际上是一个疯狂剪枝的BFS……

T3

这题……据说是树状数组的样子,反正没想出正解来,打了个30分的暴力,还把n和m打反了一分都没有= =

WA的一声哭了出来……这次炸的太惨了没得说了

然后最后是我D2T2的修改后的代码,现在能AC这个题了(至少官方数据是这样)

#include
#include
#include
#include
using std::queue;
const int cant=0x3f3f3f3f;
int n,m,dis[13][13],ans=cant;
int rlt[13],f[13],tr[13],v;
bool vis[13],can;
int num[2][2][2][2][2][2][2][2][2][2][2][2][2];

struct node{
    bool vis[13];
    int now,num,n[13],dep[13];
}a,b;
queueq;

inline int MIN(const int &a,const int &b){
    if(areturn a;return b;
}
void init(){
    for(rlt[0]=0;rlt[0]<2;rlt[0]++)
    for(rlt[1]=0;rlt[1]<2;rlt[1]++)
    for(rlt[2]=0;rlt[2]<2;rlt[2]++)
    for(rlt[3]=0;rlt[3]<2;rlt[3]++)
    for(rlt[4]=0;rlt[4]<2;rlt[4]++)
    for(rlt[5]=0;rlt[5]<2;rlt[5]++)
    for(rlt[6]=0;rlt[6]<2;rlt[6]++)
    for(rlt[7]=0;rlt[7]<2;rlt[7]++)
    for(rlt[8]=0;rlt[8]<2;rlt[8]++)
    for(rlt[9]=0;rlt[9]<2;rlt[9]++)
    for(rlt[10]=0;rlt[10]<2;rlt[10]++)
    for(rlt[11]=0;rlt[11]<2;rlt[11]++)
    for(rlt[12]=0;rlt[12]<2;rlt[12]++)
    num[rlt[0]][rlt[1]][rlt[2]][rlt[3]][rlt[4]][rlt[5]][rlt[6]][rlt[7]][rlt[8]][rlt[9]][rlt[10]][rlt[11]][rlt[12]]=cant;
}
bool comp(bool *A,int com){
    return num[A[0]][A[1]][A[2]][A[3]][A[4]][A[5]][A[6]][A[7]][A[8]][A[9]][A[10]][A[11]][A[12]]>com;
}
void change(bool *A,int cha){
    num[A[0]][A[1]][A[2]][A[3]][A[4]][A[5]][A[6]][A[7]][A[8]][A[9]][A[10]][A[11]][A[12]]=cha;
}
int main(){
    register int i,j,k,l;
    freopen("treasure.in","r",stdin);
    freopen("treasure.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;++i){
        a.vis[i]=0;a.n[i]=0;a.dep[i]=0;
        memset(dis,0x3f,sizeof(dis));
        memset(rlt,0x3f,sizeof(rlt));
    }
    for(i=1;i<=m;++i){
        scanf("%d%d%d",&j,&k,&l);
        dis[j][k]=dis[k][j]=MIN(l,dis[k][j]);
    }
    for(k=1;k<=n;++k){init();
        for(i=1;i<=n;++i){a.vis[i]=0;a.n[i]=0;a.dep[i]=0;};
        a.vis[k]=1;a.now=0;a.num=1;a.n[1]=k;a.dep[1]=1;q.push(a);
        while(!q.empty()){
            a=q.front();q.pop();
            if(comp(a.vis,a.now))change(a.vis,a.now);else continue;
            if(a.now>=ans)continue;
            if(a.num==n){ans=MIN(ans,a.now);continue;}
            for(i=1;i<=n;++i){
                b.vis[i]=a.vis[i];
                b.dep[i]=a.dep[i];
                b.n[i]=a.n[i];
            }
            b.num=a.num+1;
            for(j=1;j<=a.num;++j)
                for(i=1;i<=n;++i)
                    if(!a.vis[i]&&(dis[a.n[j]][i]!=cant)&&(a.now+a.dep[j]*dis[a.n[j]][i]<=ans)){
                        b.vis[i]=1;b.dep[b.num]=a.dep[j]+1;b.now=a.now+a.dep[j]*dis[a.n[j]][i];b.n[b.num]=i;
                        q.push(b);b.vis[i]=0;
                }
        }
    }printf("%d\n",ans);
    fclose(stdin);fclose(stdout);
    return 0;
}

你可能感兴趣的:(博客,解题报告)