场上预计得分:100+100+100+100+100+60=560(省一分数线410)
五道傻逼题+一道大搜索题……
题解:
D1T1 转圈游戏
水题送温暖~
1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<cmath>
6 #include<queue>
7 #define inf 2147483647
8 #define eps 1e-9
9 using namespace std;
10 typedef long long ll;
11 int n,m,k,x,p,num;
12 int ksm(int x,int y,int p){
13 int ret=1;
14 for(;y;y>>=1,x=(ll)x*x%p){
15 if(y&1)ret=(ll)ret*x%p;
16 }
17 return ret;
18 }
19 int main(){
20 scanf("%d%d%d%d",&n,&m,&k,&x);
21 printf("%d",((ll)m*ksm(10,k,n)%n+x)%n);
22 return 0;
23 }
D1T2 火柴排队
怎么感觉比D1T3还难啊……总是在想DP和贪心结果SB线段树就没了……
显然最优配对是分别排序后对应的数,求出对应位置直接求逆序对即可。
1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<cmath>
6 #include<queue>
7 #define inf 2147483647
8 #define eps 1e-9
9 #define mod 99999997;
10 using namespace std;
11 typedef long long ll;
12 struct node{
13 int x,id;
14 friend bool operator <(node a,node b){
15 return a.x<b.x;
16 }
17 }aa[100001],bb[100001];
18 int n,x,a[100001],b[100001],s[100001];
19 ll ans=0,t[500001];
20 void updata(int l,int r,int u,int p){
21 t[u]++;
22 if(l==r)return;
23 int mid=(l+r)/2;
24 if(p<=mid)updata(l,mid,u*2,p);
25 else updata(mid+1,r,u*2+1,p);
26 }
27 int query(int l,int r,int u,int L,int R){
28 if(L<=l&&r<=R){
29 return t[u];
30 }
31 int mid=(l+r)/2,ret=0;
32 if(L<=mid)ret+=query(l,mid,u*2,L,R);
33 if(mid<R)ret+=query(mid+1,r,u*2+1,L,R);
34 return ret;
35 }
36 int main(){
37 scanf("%d",&n);
38 for(int i=1;i<=n;i++){
39 scanf("%d",&a[i]);
40 aa[i].x=a[i];
41 aa[i].id=i;
42 }
43 for(int i=1;i<=n;i++){
44 scanf("%d",&b[i]);
45 bb[i].x=b[i];
46 bb[i].id=i;
47 }
48 sort(aa+1,aa+n+1);
49 sort(bb+1,bb+n+1);
50 for(int i=1;i<=n;i++){
51 s[aa[i].id]=bb[i].id;
52 }
53 for(int i=1;i<=n;i++){
54 ans=(ans+s[i]-query(1,n,1,1,s[i])-1)%mod;
55 updata(1,n,1,s[i]);
56 }
57 printf("%d",ans);
58 return 0;
59 }
D1T3 火车运输
傻逼题,在最大生成树上跑树上倍增即可。
(我AKDay1啦!)
1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<cmath>
6 #include<queue>
7 #define inf 2147483647
8 #define eps 1e-9
9 using namespace std;
10 typedef long long ll;
11 struct edge{
12 int v,w,next;
13 }a[100001];
14 struct _edge{
15 int u,v,w;
16 friend bool operator <(_edge a,_edge b){
17 return a.w>b.w;
18 }
19 }e[50001];
20 int n,m,u,v,tot=0,head[10001],dep[10001],fa[10001],f[10001][15],mi[10001][15];
21 bool used[10001];
22 int ff(int u){
23 return fa[u]==u?u:fa[u]=ff(fa[u]);
24 }
25 void add(int u,int v,int w){
26 a[++tot].v=v;
27 a[tot].w=w;
28 a[tot].next=head[u];
29 head[u]=tot;
30 }
31 void dfs(int u,int ff,int dpt,int minn){
32 used[u]=true;
33 dep[u]=dpt;
34 f[u][0]=ff;
35 mi[u][0]=minn;
36 for(int i=1;i<=14;i++){
37 f[u][i]=f[f[u][i-1]][i-1];
38 mi[u][i]=min(mi[u][i-1],mi[f[u][i-1]][i-1]);
39 }
40 for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
41 int v=a[tmp].v;
42 if(v!=ff){
43 dfs(v,u,dpt+1,a[tmp].w);
44 }
45 }
46 }
47 int work(int u,int v){
48 if(dep[u]<dep[v])swap(u,v);
49 int ret=inf,l=dep[u]-dep[v];
50 for(int i=14;i>=0;i--){
51 if((1<<i)&l){
52 ret=min(ret,mi[u][i]);
53 u=f[u][i];
54 }
55 }
56 if(u==v)return ret;
57 for(int i=14;i>=0;i--){
58 if(f[u][i]!=f[v][i]){
59 ret=min(ret,min(mi[u][i],mi[v][i]));
60 u=f[u][i],v=f[v][i];
61 }
62 }
63 return min(ret,min(mi[u][0],mi[v][0]));
64 }
65 int main(){
66 memset(head,-1,sizeof(head));
67 scanf("%d%d",&n,&m);
68 for(int i=1;i<=n;i++)fa[i]=i;
69 for(int i=1;i<=m;i++){
70 scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
71 }
72 sort(e+1,e+m+1);
73 for(int i=1;i<=m;i++){
74 int u=e[i].u,v=e[i].v,fu=ff(u),fv=ff(v);
75 if(fu!=fv){
76 add(u,v,e[i].w);
77 add(v,u,e[i].w);
78 fa[fu]=fv;
79 }
80 }
81 for(int i=1;i<=n;i++){
82 if(!used[i])dfs(i,0,0,inf);
83 }
84 scanf("%d",&m);
85 for(int i=1;i<=m;i++){
86 scanf("%d%d",&u,&v);
87 printf("%d
",(ff(u)==ff(v))?work(u,v):-1);
88 }
89 return 0;
90 }
D2T1 积木大赛
水题送温暖~
ps:此题同NOIP2018D1T1铺设道路
1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<cmath>
6 #include<queue>
7 #define inf 2147483647
8 #define eps 1e-9
9 using namespace std;
10 typedef long long ll;
11 int n,x,las=0,ans=0;
12 int main(){
13 scanf("%d",&n);
14 for(int i=1;i<=n;i++){
15 scanf("%d",&x);
16 if(x>las)ans+=x-las;
17 las=x;
18 }
19 printf("%d",ans);
20 return 0;
21 }
D2T2 花匠
这是D2T2????(原数据范围$10^5$,LOJ加到了$2 imes 10^6$)
结论是移一位两种情况就互换了
1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<cmath>
6 #include<queue>
7 #define inf 2147483647
8 #define eps 1e-9
9 using namespace std;
10 typedef long long ll;
11 int n,x,h0,ans1=1,ans2=1;
12 int main(){
13 scanf("%d%d",&n,&h0);
14 for(int i=2;i<=n;i++){
15 scanf("%d",&x);
16 if(x>h0)ans1=max(ans1,ans2+1);
17 if(x<h0)ans2=max(ans2,ans1+1);
18 h0=x;
19 }
20 printf("%d",max(ans1,ans2));
21 return 0;
22 }
D2T3 华容道
可能其他题的难度全集中到这题来了?太久没做过搜索题了,场上$O(qn^4)$60分暴力滚粗;
正解就是预处理每一格向四个方向走的距离然后每次询问做spfa……
1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<cmath>
6 #include<queue>
7 #define inf 0x7f7f7f7f
8 #define eps 1e-9
9 #define DCSB {puts("-1");return;}
10 using namespace std;
11 typedef long long ll;
12 const int way[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
13 struct node{
14 int x,y,w;
15 node(int _x=0,int _y=0,int _w=0){
16 x=_x,y=_y,w=_w;
17 }
18 };
19 int n,m,q,ans,ex,ey,sx,sy,tx,ty,f[31][31][4],dis[31][31],mp[31][31],go[31][31][4][4];
20 bool isin[31][31][4];
21 bool chk(int x,int y){
22 return x<1||x>n||y<1||y>m||!mp[x][y];
23 }
24 int bfs(int sx,int sy,int tx,int ty){
25 if(!mp[sx][sy]||!mp[tx][ty])return inf;
26 queue<node>q;
27 memset(dis,0x7f,sizeof(dis));
28 dis[sx][sy]=0;
29 q.push((node){sx,sy,0});
30 while(!q.empty()){
31 node u=q.front();
32 q.pop();
33 if(u.x==tx&&u.y==ty)return dis[tx][ty];
34 for(int k=0;k<4;k++){
35 int xx=u.x+way[k][0],yy=u.y+way[k][1];
36 if(chk(xx,yy)||dis[xx][yy]!=inf)continue;
37 dis[xx][yy]=dis[u.x][u.y]+1;
38 q.push((node){xx,yy,0});
39 }
40 }
41 return inf;
42 }
43 void _(){
44 for(int i=1;i<=n;i++){
45 for(int j=1;j<=m;j++){
46 int ch=mp[i][j];
47 mp[i][j]=0;
48 for(int k=0;k<4;k++){
49 for(int l=0;l<4;l++){
50 go[i][j][k][l]=bfs(i+way[k][0],j+way[k][1],i+way[l][0],j+way[l][1]);
51 }
52 }
53 mp[i][j]=ch;
54 }
55 }
56 }
57 void spfa(){
58 queue<node>q;
59 memset(isin,0,sizeof(isin));
60 for(int k=0;k<4;k++){
61 if(f[sx][sy][k]!=inf){
62 q.push((node){sx,sy,k});
63 isin[sx][sy][k]=true;
64 }
65 }
66 while(!q.empty()){
67 node u=q.front();
68 q.pop();
69 int x=u.x,y=u.y,w=u.w;
70 isin[x][y][w]=false;
71 for(int k=0;k<4;k++){
72 int xx=x+way[k][0],yy=y+way[k][1];
73 if(chk(xx,yy)||go[x][y][w][k]==inf)continue;
74 if(f[xx][yy][k^1]>f[x][y][w]+go[x][y][w][k]+1){
75 f[xx][yy][k^1]=f[x][y][w]+go[x][y][w][k]+1;
76 if(!isin[xx][yy][k^1]){
77 q.push((node){xx,yy,k^1});
78 isin[xx][yy][k^1]=true;
79 }
80 }
81 }
82 }
83 }
84 void work(){
85 if(sx==tx&&sy==ty){
86 puts("0");
87 return;
88 }
89 if((sx==ex&&sy==ey)||chk(sx,sy)||chk(tx,ty)||chk(ex,ey))DCSB;
90 memset(f,0x7f,sizeof(f));
91 mp[sx][sy]=0;
92 for(int k=0;k<4;k++){
93 f[sx][sy][k]=bfs(ex,ey,sx+way[k][0],sy+way[k][1]);
94 }
95 mp[sx][sy]=1;
96 spfa();
97 ans=inf;
98 for(int k=0;k<4;k++){
99 ans=min(ans,f[tx][ty][k]);
100 }
101 printf("%d
",ans==inf?-1:ans);
102 }
103 int main(){
104 scanf("%d%d%d",&n,&m,&q);
105 for(int i=1;i<=n;i++){
106 for(int j=1;j<=m;j++){
107 scanf("%d",&mp[i][j]);
108 }
109 }
110 _();
111 /*for(int i=1;i<=n;i++){
112 for(int j=1;j<=m;j++){
113 for(int k=0;k<4;k++){
114 for(int l=0;l<4;l++){
115 printf("%d ",go[i][j][k][l]);
116 }
117 }
118 puts("");
119 }
120 puts("");
121 }*/
122 for(int i=1;i<=q;i++){
123 scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);
124 work();
125 }
126 return 0;
127 }
总结:
1.两个小时干完五题然后发呆,D1一小时写完,D2前两题加起来800B……就D2T3有点代码量;
2.搜索姿势水平要提高。