1. 程式人生 > >[NOIP TG]來自一個打崩的分數比得的分數都高的蒟蒻的怨念

[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<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
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; queue<node>q; inline int MIN(const int &a,const int &b){ if(a<b)return 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; }