NOIP2009代码

一.潜伏者(有一一对应的特殊错误关系,可用代码中二重循环判断)

View Code
 1 program spy(input,output);
2 var a:array['A'..'Z'] of char;
3 i,j:longint;
4 s1,s2,s3:ansistring;
5 ch:char;
6 begin
7 assign(input,'spy.in');reset(input);
8 assign(output,'spy.out');rewrite(output);
9 fillchar(a,sizeof(a),'*');
10 readln(s1);
11 readln(s2);
12 readln(s3);
13 for i:=1 to length(s1) do
14 for j:=i+1 to length(s1) do
15 if (s2[i]=s2[j])and(s1[i]<>s1[j]) then
16 begin
17 write('Failed');
18 close(output);
19 halt;
20 end;
21 for i:=1 to length(s1) do
22 begin
23 if(a[s1[i]]<>'*')and(a[s1[i]]<>s2[i]) then
24 begin
25 write('Failed');
26 close(output);
27 halt;
28 end
29 else
30 a[s1[i]]:=s2[i];
31 end;
32 for ch:='A' to 'Z' do
33 if a[ch]='*' then
34 begin
35 write('Failed');
36 close(output);
37 halt;
38 end;
39 for i:=1 to length(s3) do
40 write(a[s3[i]]);
41 close(input);
42 close(output);
43 end.

二.hankson的趣味题(第十个点的特判)

View Code
  1 program harkson(input,output);
2 type
3 numbertype = array[0..6000] of int64;
4 var
5 prime : array[0..6000] of longint;
6 list_a1,list_a0,list_b1,list_b0,list_a0a1,list_b1b0,list_x : numbertype;
7 have,v : array[0..60000] of boolean;
8 a0,a1,b0,b1,m,e,tot,ans : longint;
9 flag : boolean;
10 procedure clean;
11 begin
12 fillchar(list_a0,sizeof(list_a0),0);
13 fillchar(list_a1,sizeof(list_a1),0);
14 fillchar(list_b0,sizeof(list_b0),0);
15 fillchar(list_b1,sizeof(list_b1),0);
16 fillchar(have,sizeof(have),false);
17 fillchar(list_x,sizeof(list_x),0);
18 fillchar(v,sizeof(v),false);
19 end; { clean }
20 procedure init;
21 begin
22 readln(a0,a1,b0,b1);
23 end; { init }
24 procedure previous;
25 var
26 i,j : longint;
27 begin
28 tot:=0;
29 for i:=2 to 50000 do
30 if not v[i] then
31 begin
32 inc(tot);
33 prime[tot]:=i;
34 j:=i+i;
35 while j<=50000 do
36 begin
37 v[j]:=true;
38 j:=j+i;
39 end;
40 end;
41 end; { previous }
42 procedure challenge(now : longint;var goal:numbertype );
43 var
44 i : longint;
45 begin
46 for i:=1 to tot do
47 begin
48 if (now mod prime[i]=0)and(now<>1) then
49 while (now mod prime[i]=0)and(now<>0) do
50 begin
51 inc(goal[i]);
52 now:=now div prime[i];
53 end;
54 if now=1 then
55 break;//较强的剪枝,没有会超时
56 end;
57 if now<>1 then
58 goal[tot+1]:=now;
59 end; { challenge }
60 procedure main;
61 var
62 i : longint;
63 begin
64 challenge(a0,list_a0);
65 challenge(a1,list_a1);
66 challenge(b0,list_b0);
67 challenge(b1,list_b1);
68 list_x:=list_a1; {x的最小值为a1}
69 for i:=1 to tot+1 do
70 begin
71 list_a0a1[i]:=list_a0[i]-list_a1[i];{以质因子相减求得a0/a1的质因子}
72 list_b1b0[i]:=list_b1[i]-list_b0[i];{同理,求的b0/b1}
73 if list_a0a1[i]<>0 then
74 have[i]:=true;{have标记a0/a1是否含有第i个质因数}
75 end;
76 flag:=true;
77 for i:=1 to tot do
78 if (list_b1[i]<>0)and(list_b1b0[i]<>0) then
79 if list_x[i]<list_b1[i] then
80 begin
81 if have[i] then
82 begin
83 flag:=false;
84 break;
85 end;
86 list_x[i]:=list_b1[i];
87 end
88 else
89 if list_x[i]>list_b1[i] then
90 begin
91 flag:=false;
92 break;
93 end;
94 if (list_x[tot+1]=0)and(list_b1[tot+1]=list_b1b0[tot+1])and(list_b1[tot+1]>0)and(list_a0a1[tot+1]<>list_b1[tot+1])then
95 list_x[tot+1]:=list_b1[tot+1];
96 if (list_x[tot+1]=list_a0a1[tot+1])and(list_x[tot+1]>0) then
97 flag:=false;
98 if (list_x[tot+1]>0)and(list_b1[tot+1]>0)and(list_x[tot+1]<>list_b1[tot+1]) then
99 flag:=false;
100 if not flag then
101 begin
102 writeln('0');
103 exit;
104 end;
105 ans:=1;
106 for i:=1 to tot do
107 if list_a0a1[i]=0 then
108 ans:=ans*(list_b1[i]-list_x[i]+1);
109 if (list_x[tot+1]=0)and(list_b1[tot+1]>0) then
110 inc(ans,ans);
111 writeln(ans);
112 end; { main }
113 begin
114 assign(input,'son.in');reset(input);
115 assign(output,'son.out');rewrite(output);
116 readln(m);
117 previous;
118 for e:=1 to m do
119 begin
120 clean;
121 init;
122 main;
123 end;
124 close(input);
125 close(output);
126 end.

三.最优贸易(前向星效果不太好)

View Code
  1 program trade(input,output);
2 var
3 x,y : array[0..1000001] of longint;
4 f,w,min,max : array[0..110000] of longint;
5 n,m,ans : longint;
6 v : array[0..100010] of boolean;
7 q : array[0..1000000] of longint;
8 procedure swap(var aa,bb: longint );
9 var
10 tt : longint;
11 begin
12 tt:=aa;
13 aa:=bb;
14 bb:=tt;
15 end; { swap }
16 function minn(aa,bb :longint ):longint;
17 begin
18 if aa<bb then
19 exit(aa);
20 exit(bb);
21 end; { min }
22 function maxn(aa,bb :longint ):longint;
23 begin
24 if aa>bb then
25 exit(aa);
26 exit(bb);
27 end; { maxn }
28 procedure sort(p,q : longint );
29 var
30 i,j,m : longint;
31 begin
32 i:=p;
33 j:=q;
34 m:=x[(i+j)>>1];
35 repeat
36 while x[i]<m do
37 inc(i);
38 while x[j]>m do
39 dec(j);
40 if i<=j then
41 begin
42 swap(x[i],x[j]);
43 swap(y[i],y[j]);
44 inc(i);
45 dec(j);
46 end;
47 until i>j;
48 if i<q then sort(i,q);
49 if j>p then sort(p,j);
50 end; { sort }
51 procedure init;
52 var
53 i,x1,y1,k : longint;
54 tot : longint;
55 begin
56 readln(n,m);
57 for i:=1 to n do
58 read(w[i]);
59 tot:=0;
60 for i:=1 to m do
61 begin
62 readln(x1,y1,k);
63 inc(tot);
64 x[tot]:=x1;
65 y[tot]:=y1;
66 if k=2 then
67 begin
68 inc(tot);
69 x[tot]:=y1;
70 y[tot]:=x1;
71 end;
72 end;
73 m:=tot;
74 end; { init }
75 procedure previous;
76 var
77 i : longint;
78 begin
79 fillchar(f,sizeof(f),0);
80 for i:=1 to m do
81 if f[x[i]]=0 then
82 f[x[i]]:=i;
83 f[n+1]:=m+1;
84 for i:=m downto 1 do
85 if f[i]=0 then
86 f[i]:=f[i+1];
87 end; { previous }
88 procedure spfamin();
89 var
90 head,tail : longint;
91 i,tmp : longint;
92 begin
93 fillchar(v,sizeof(v),false);
94 fillchar(min,sizeof(min),63);
95 head:=0;tail:=1;
96 q[1]:=1;
97 v[1]:=true;
98 min[1]:=w[1];
99 while head<tail do
100 begin
101 inc(head);
102 v[q[head]]:=false;
103 for i:=f[q[head]] to f[q[head]+1]-1 do
104 begin
105 tmp:=minn(min[q[head]],w[y[i]]);
106 if tmp<min[y[i]] then
107 begin
108 min[y[i]]:=tmp;
109 if not v[y[i]] then
110 begin
111 inc(tail);
112 q[tail]:=y[i];
113 v[y[i]]:=true;
114 end;
115 end;
116 end;
117 end;
118 end; { spfamin }
119 procedure change;
120 var
121 i : longint;
122 begin
123 for i:=1 to m do
124 swap(x[i],y[i]);
125 end; { change }
126 procedure spfamax();
127 var
128 head,tail : longint;
129 tmp,i : longint;
130 begin
131 fillchar(v,sizeof(v),false);
132 fillchar(max,sizeof(max),0);
133 head:=0;
134 tail:=1;
135 q[1]:=n;
136 v[n]:=true;
137 max[n]:=w[n];
138 while head<tail do
139 begin
140 inc(head);
141 v[q[head]]:=false;
142 for i:=f[q[head]] to f[q[head]+1]-1 do
143 begin
144 tmp:=maxn(max[x[i]],w[y[i]]);
145 if tmp>max[y[i]] then
146 begin
147 max[y[i]]:=tmp;
148 if not v[y[i]] then
149 begin
150 inc(tail);
151 q[tail]:=y[i];
152 v[y[i]]:=true;
153 end;
154 end;
155 end;
156 end;
157 end; { spfa2 }
158 procedure main;
159 var
160 i : longint;
161 begin
162 for i:=1 to n do
163 if max[i]-min[i]>ans then
164 ans:=max[i]-min[i];
165 end; { main }
166 procedure print;
167 begin
168 writeln(ans);
169 end; { print }
170 begin
171 assign(input,'trade.in');reset(input);
172 assign(output,'trade.out');rewrite(output);
173 init;
174 sort(1,m);
175 previous;
176 spfamin;
177 change;
178 sort(1,m);
179 previous;
180 spfamax;
181 main;
182 print;
183 close(input);
184 close(output);
185 end.

四.靶形数独(有点囧,卡时了,有一个点过不了)

View Code
  1 program sudoku(input,output);
2 type
3 node = record
4 s : array[1..9] of boolean;
5 l,x,y : longint;
6 end;
7 var
8 a : array[1..9,1..9] of byte;
9 ff : array[1..9,1..9] of byte;
10 v,vv,vvv : array[0..9] of boolean;
11 next : array[1..81] of node;
12 num,sum,ans,dfn : longint;
13 hang,lie,small : array[1..9,1..9] of byte;
14 const
15 color : array[1..9,1..9] of byte=((1,1,1,2,2,2,3,3,3),
16 (1,1,1,2,2,2,3,3,3),
17 (1,1,1,2,2,2,3,3,3),
18 (4,4,4,5,5,5,6,6,6),
19 (4,4,4,5,5,5,6,6,6),
20 (4,4,4,5,5,5,6,6,6),
21 (7,7,7,8,8,8,9,9,9),
22 (7,7,7,8,8,8,9,9,9),
23 (7,7,7,8,8,8,9,9,9));
24 procedure init;
25 var
26 i,j : longint;
27 begin
28 for i:=1 to 81 do
29 begin
30 next[i].l:=0;
31 fillchar(next[i].s,sizeof(next[i].s),false);
32 end;
33 fillchar(a,sizeof(a),0);
34 for i:=1 to 9 do
35 for j:=1 to 9 do
36 read(a[i,j]);
37 for i:=1 to 9 do
38 for j:=1 to 9 do
39 ff[i,j]:=6;
40 for i:=2 to 8 do
41 for j:=2 to 8 do
42 ff[i,j]:=7;
43 for i:=3 to 7 do
44 for j:=3 to 7 do
45 ff[i,j]:=8;
46 for i:=4 to 6 do
47 for j:=4 to 6 do
48 ff[i,j]:=9;
49 ff[5,5]:=10;
50 end; { init }
51 procedure make;
52 var
53 i,j,k,l,o : longint;
54 begin
55 for i:=1 to 9 do
56 for j:=1 to 9 do
57 begin
58 inc(sum,ff[i,j]*a[i,j]);
59 if a[i,j]<>0 then
60 begin
61 hang[i,a[i,j]]:=1;
62 lie[j,a[i,j]]:=1;
63 small[color[i,j],a[i,j]]:=1;
64 end;
65 end;
66 for i:=1 to 9 do
67 for j:=1 to 9 do
68 if a[i,j]=0 then
69 begin
70 fillchar(v,sizeof(v),false);
71 fillchar(vv,sizeof(vv),false);
72 fillchar(vvv,sizeof(vvv),false);
73 for k:=1 to 9 do
74 begin
75 v[a[i,k]]:=true;
76 vv[a[k,j]]:=true;
77 for l:=1 to 9 do
78 for o:=1 to 9 do
79 if color[l,o]=color[i,j] then
80 vvv[a[l,o]]:=true;
81 end;
82 inc(num);
83 next[num].x:=i;
84 next[num].y:=j;
85 for k:=1 to 9 do
86 begin
87 v[k]:=(v[k])or(vv[k])or(vvv[k]);
88 if not v[k] then
89 begin
90 next[num].s[k]:=true;
91 inc(next[num].l);
92 end;
93 end;
94 end;
95 end; { make }
96 procedure swap(var aa,bb :longint );
97 var
98 t : longint;
99 begin
100 t:=aa;
101 aa:=bb;
102 bb:=t;
103 end; { swap }
104 procedure sswap(var aa,bb :boolean );
105 var
106 t : boolean;
107 begin
108 t:=aa;
109 aa:=bb;
110 bb:=t;
111 end; { sswap }
112 procedure sort(p,q: longint );
113 var
114 i,j,m,k : longint;
115 begin
116 i:=p;
117 j:=q;
118 m:=(i+j)>>1;
119 repeat
120 while next[i].l<next[m].l do
121 inc(i);
122 while next[j].l>next[m].l do
123 dec(j);
124 if i<=j then
125 begin
126 swap(next[i].l,next[j].l);
127 swap(next[i].x,next[j].x);
128 swap(next[i].y,next[j].y);
129 for k:=1 to 9 do
130 sswap(next[i].s[k],next[j].s[k]);
131 inc(i);
132 dec(j);
133 end;
134 until i>j;
135 if i<q then sort(i,q);
136 if j>p then sort(p,j);
137 end; { sort }
138 procedure dfs(ii: longint );
139 var
140 i,xx,yy : longint;
141 begin
142 if ii=num+1 then
143 begin
144 if sum>ans then
145 ans:=sum;
146 exit;
147 end;
148 if sum+(num-ii+1)*9*10<ans then
149 exit;
150 inc(dfn);
151 if dfn>22000000 then
152 begin
153 writeln(ans);
154 close(output);
155 halt;
156 end;
157 xx:=next[ii].x;
158 yy:=next[ii].y;
159 for i:=1 to 9 do
160 if next[ii].s[i] then
161 if hang[xx,i]=0 then
162 if lie[yy,i]=0 then
163 if small[color[xx,yy],i]=0 then
164 begin
165 inc(sum,i*ff[xx,yy]);
166 inc(hang[xx,i]);
167 inc(lie[yy,i]);
168 inc(small[color[xx,yy],i]);
169 dfs(ii+1);
170 dec(sum,i*ff[xx,yy]);
171 dec(hang[xx,i]);
172 dec(lie[yy,i]);
173 dec(small[color[xx,yy],i]);
174 end;
175 end; { dfs }
176 procedure print;
177 var
178 i,j : longint;
179 begin
180 if ans <>0 then
181 writeln(ans)
182 else
183 writeln('-1');
184 end; { print }
185 begin
186 assign(input,'sudoku.in');reset(input);
187 assign(output,'sudoku.out');rewrite(output);
188 init;
189 make;
190 sort(1,num);
191 dfs(1);
192 print;
193 close(input);
194 close(output);
195 end.

不懂仍然请留言,会得到及时解答。
看了看位运算之后,发现有些门道,写了一个位运算版的,超简洁,还快,不卡时最大点1.7++。

View Code
  1 program sudoku(input,output);
2 type
3 node = record
4 x,y : integer;
5 end;
6 var
7 color : array[1..9,1..9] of integer=((1,1,1,2,2,2,3,3,3),
8 (1,1,1,2,2,2,3,3,3),
9 (1,1,1,2,2,2,3,3,3),
10 (4,4,4,5,5,5,6,6,6),
11 (4,4,4,5,5,5,6,6,6),
12 (4,4,4,5,5,5,6,6,6),
13 (7,7,7,8,8,8,9,9,9),
14 (7,7,7,8,8,8,9,9,9),
15 (7,7,7,8,8,8,9,9,9));
16 multiply:array[1..9,1..9] of integer=((6,6,6,6,6,6,6,6,6),
17 (6,7,7,7,7,7,7,7,6),
18 (6,7,8,8,8,8,8,7,6),
19 (6,7,8,9,9,9,8,7,6),
20 (6,7,8,9,10,9,8,7,6),
21 (6,7,8,9,9,9,8,7,6),
22 (6,7,8,8,8,8,8,7,6),
23 (6,7,7,7,7,7,7,7,6),
24 (6,6,6,6,6,6,6,6,6));
25 q:array[0..1000] of node;
26 a:array[1..9,1..9] of integer;
27 tot:integer;
28 hang,lie,little:array[1..9] of integer;
29 ans,tmp:int64;
30 procedure init;
31 var
32 i,j : longint;
33 begin
34 for i:=1 to 9 do
35 for j:=1 to 9 do
36 read(a[i,j]);
37 end; { init }
38 procedure make;
39 var
40 i,j : longint;
41 begin
42 for i:=9 downto 1 do
43 for j:=1 to 9 do
44 if a[i,j]=0 then
45 begin
46 inc(tot);
47 q[tot].x:=i;
48 q[tot].y:=j;
49 end
50 else
51 inc(ans,a[i,j]*multiply[i,j]);
52 tmp:=ans;
53 fillchar(hang,sizeof(hang),0);
54 fillchar(lie,sizeof(lie),0);
55 fillchar(little,sizeof(little),0);
56 for i:=1 to 9 do
57 for j:=1 to 9 do
58 if a[i,j]<>0 then
59 hang[i]:=hang[i] or (1<<(a[i,j]-1));
60 for i:=1 to 9 do
61 for j:=1 to 9 do
62 if a[i,j]<>0 then
63 lie[j]:=lie[j] or (1<<(a[i,j]-1));
64 for i:=1 to 9 do
65 for j:=1 to 9 do
66 if a[i,j]<>0 then
67 little[color[i,j]]:=little[color[i,j]] or (1<<(a[i,j]-1));
68 end; { make }
69 procedure dfs(now : integer;sum:int64 );
70 var
71 i : integer;
72 begin
73 if now=tot+1 then
74 begin
75 if sum>ans then
76 ans:=sum;
77 exit;
78 end;
79 for i:=1 to 9 do
80 if (hang[q[now].x] and (1<<(i-1))=0) then
81 if (lie[q[now].y] and (1<<(i-1))=0) then
82 if (little[color[q[now].x,q[now].y]] and (1<<(i-1))=0) then
83 begin
84 hang[q[now].x]:=hang[q[now].x] or (1<<(i-1));
85 lie[q[now].y]:=lie[q[now].y] or (1<<(i-1));
86 little[color[q[now].x,q[now].y]]:=little[color[q[now].x,q[now].y]] or (1<<(i-1));
87 dfs(now+1,sum+i*multiply[q[now].x,q[now].y]);
88 hang[q[now].x]:=hang[q[now].x]-(1<<(i-1));
89 lie[q[now].y]:=lie[q[now].y]-(1<<(i-1));
90 little[color[q[now].x,q[now].y]]:=little[color[q[now].x,q[now].y]]-(1<<(i-1));
91 end;
92 end; { dfs }
93 procedure print;
94 begin
95 if tmp=ans then
96 writeln(-1)
97 else
98 writeln(ans);
99 end; { print }
100 begin
101 assign(input,'sudoku.in');reset(input);
102 assign(output,'sudoku.out');rewrite(output);
103 init;
104 make;
105 dfs(1,tmp);
106 print;
107 close(input);
108 close(output);
109 end.





原文地址:https://www.cnblogs.com/neverforget/p/noip2009.html