[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;
}