NOI2013小Q的修炼
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NOI2013小Q的修炼相关的知识,希望对你有一定的参考价值。
题目链接:http://uoj.ac/problem/123
又开提答坑啦,要不是一定要讲题谁他妈要这样伤害自己
CASE 1,2
首先可以打一个通用暴力,用于模拟操作过程,对于每一个操作随机一个选择,然后跑多次记录答案。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 #include<string> 9 #include<ctime> 10 using namespace std; 11 #define maxn 1000010 12 #define llg long long 13 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 14 llg n,m,dl[maxn],tail,anst,ans[maxn],val[maxn],maxl,cs; 15 llg T=1; 16 char ch,s[maxn]; 17 18 llg next_x(llg x){x++; while (s[x]==‘ ‘) x++; return x;} 19 20 struct node 21 { 22 llg type; 23 llg t1,v1,t2,v2,fu,to1,to2; 24 }a[maxn]; 25 26 llg make_number(llg &x) 27 { 28 llg val=0,p=1; 29 if (s[x]==‘-‘) x++,p=-1; 30 while (s[x]>=‘0‘ && s[x]<=‘9‘) 31 { 32 val*=10; 33 val+=s[x]-‘0‘; 34 x++; 35 } 36 return val*p; 37 } 38 39 void Decompression_(llg i) 40 { 41 42 llg x=1; 43 if (s[x]==‘v‘) 44 { 45 a[i].type=1; 46 x=next_x(x); 47 a[i].v1=make_number(x); 48 x=next_x(x); 49 if (s[x]==‘+‘) a[i].fu=1;else a[i].fu=-1; 50 x=next_x(x); 51 if (s[x]==‘c‘) a[i].t2=0; else a[i].t2=1; 52 x=next_x(x); 53 a[i].v2=make_number(x); 54 } 55 if (s[x]==‘s‘) 56 { 57 a[i].type=2; 58 x=next_x(x); 59 a[i].to1=make_number(x); 60 x=next_x(x); 61 a[i].to2=make_number(x); 62 } 63 if (s[x]==‘i‘) 64 { 65 a[i].type=3; 66 x=next_x(x); 67 if (s[x]==‘c‘) a[i].t1=0; else a[i].t1=1; 68 x=next_x(x); 69 a[i].v1=make_number(x); 70 x=next_x(x); 71 if (s[x]==‘c‘) a[i].t2=0; else a[i].t2=1; 72 x=next_x(x); 73 a[i].v2=make_number(x); 74 x=next_x(x); 75 a[i].to1=make_number(x); 76 x=next_x(x); 77 a[i].to2=make_number(x); 78 } 79 } 80 81 bool pd(char ch) 82 { 83 if (ch>=‘0‘ && ch<=‘9‘) return 1; 84 if (ch==‘v‘ || ch==‘i‘ || ch==‘+‘ || ch==‘-‘ || ch==‘s‘ || ch==‘c‘ || ch==‘ ‘) return 1; 85 return 0; 86 } 87 88 void init() 89 { 90 cin>>n>>m; 91 ch=getchar(); 92 for (llg i=1;i<=n;i++) 93 { 94 llg len=0; 95 ch=getchar(); 96 while (pd(ch)) {s[++len]=ch; ch=getchar();} 97 Decompression_(i); 98 for (llg i=0;i<=len+1;i++) s[i]=‘\\0‘; 99 } 100 } 101 102 void work() 103 { 104 cs=0; 105 llg x=1,cho; 106 tail=0; 107 for (llg i=1;i<=m;i++) val[i]=0; 108 while (x>=1 && x<=n) 109 { 110 if (a[x].type==1) 111 { 112 if (a[x].t2) val[a[x].v1]+=val[a[x].v2]*a[x].fu; 113 else val[a[x].v1]+=a[x].v2*a[x].fu; 114 x++; 115 } 116 if (a[x].type==2) 117 { 118 cs++; 119 if (cs>1000000) {return ;} 120 cho=rand()%2+1; 121 if (cho==1) x=a[x].to1; else x=a[x].to2; 122 dl[++tail]=cho; 123 } 124 if (a[x].type==3) 125 { 126 llg val1,val2; 127 if (a[x].t1) val1=val[a[x].v1];else val1=a[x].v1; 128 if (a[x].t2) val2=val[a[x].v2];else val2=a[x].v2; 129 if (val1<val2) x=a[x].to1; else x=a[x].to2; 130 } 131 } 132 } 133 134 int main() 135 { 136 yyj("train7"); 137 init(); 138 srand(time(NULL)); 139 fclose(stdin); 140 // freopen("make.in","r",stdin); 141 maxl=(llg)1e16*-1; 142 T=300000000; 143 while (T--) 144 { 145 // system("make.exe"); 146 work(); 147 if (val[1]>maxl && cs<=1000000) 148 { 149 maxl=val[1]; 150 anst=tail; 151 for (llg i=1;i<=anst;i++) ans[i]=dl[i]; 152 } 153 } 154 // cout<<maxl<<endl; 155 for (llg i=1;i<=anst;i++) cout<<ans[i]<<endl; 156 return 0; 157 }
这样可以过第一,二个点,然后一共有31分。。。。
Ans1:
1 1 2 1 3 1 4 1
Ans2:
1 1 2 1 3 2 4 1 5 2 6 1 7 2 8 1 9 1 10 2 11 1 12 2 13 1 14 1 15 1 16 1 17 2 18 2 19 1 20 1 21 1 22 1 23 2 24 1 25 1
CASE 3
可以发现有很多块,但是每一个块会根据在这个块中的所有变量的变化来修改变量1的值,每一个块中又分为10+个小块,小块中是对于变量2-m的修改,小块首有选择语句,可以选择是否跳过这个小块。
块与块之间又互不影响,因为块尾会把除了变量1的所有变量全部清空。
所以说,我们可以爆搜每一个块中的小块的决策,然后统计答案即可。
以上是关于NOI2013小Q的修炼的主要内容,如果未能解决你的问题,请参考以下文章