【noip2017】

D1T1 小凯的诱惑疑惑

证明:链接

不妨设 a<b 假设答案为 x

x ≡ ma (mod b) (1 ≤ m ≤ b − 1)

x = ma + nb (1 ≤ m ≤ b − 1)

显然当n 0 时 x 可以用a,b表示出来

因此当 n=−1 x 取得最大值,此时 x = ma − b

显然当 m 取得最大值 b − 1x 最大,此时 x=(b−1)a−b=ab−a−b

因此 a, b 所表示不出的最大的数是 ab−a−b

(超小声bb)这个比较好理解 还有注意要输出long long 就很难受,不开long long 是60

 1 /*
 2 id:gww
 3 language:
 4 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊 
 5 */
 6 #include<bits/stdc++.h> 
 7 using namespace std;
 8 long long read()  //This is 读入优化 
 9 {
10     long long x=0,w=0;char ch=0;
11     while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
12     while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
13     return w?-x:x;
14 }
15  
16 int main()
17 {
18     long long a,b;
19     a=read(),b=read();
20     printf("%lld",(a*b)-a-b);
21     return 0;
22 }
View Code

D1T2 时间复杂度

这个模拟太恶心了,靠死不想模拟了 好像是因为中间夹杂了我的莫名其妙的判断ERR导致爆炸 还有我莫名其妙的输入

对于 30%的数据:不存在语法错误,数据保证小明给出的每个程序的前 L/2 行一定为以 F 开头的语句,第 L/2+1行至第 L 行一定为以 E 开头的语句,L≤10,若 xy 均 为整数,x一定小于 y,且只有 y 有可能为 n

对于 50%的数据:不存在语法错误,L≤100,且若 xy 均为整数,x 一定小于 y, 且只有 y 有可能为 n

对于 70%的数据:不存在语法错误,L≤100

对于 100%的数据:L≤100

 1 /*
 2 id:gww
 3 language:
 4 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊 
 5 */
 6 #include<bits/stdc++.h>
 7 using namespace std;
 8 const int N=100000+2;
 9 const int M=200000+2;
10 const int inf=0x3f3f3f3f;
11 char a[105],dm[1002],ii[105];
12 int l,nn;
13 int read()
14 {
15     int w=0,x=0;char ch=0;
16     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
17     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
18     return w?-x:x;
19 }
20  
21 void clean()
22 {
23     l=nn=0;
24     memset(dm,0,sizeof(dm));
25 }
26  
27 int main()
28 {
29     int t=read();
30     while(t--)
31     {
32         clean();
33         scanf("%d %s",&l,a+1);
34         int la=strlen(a+1),on=0,pn=0,nnn=0;
35         bool dx=0,xt=0;
36         for(int i=1;i<=la;i++)
37         {
38             if(a[i]>='0'&&a[i]<='9')
39             on=on*10+a[i]-'0';
40             if(a[i]=='n')
41             pn=1;
42         }
43         if(1&l)
44         {
45             printf("ERR\n");
46             for(int i=0;i<=l;i++)
47             gets(dm);
48         }
49         for(int i=0;i<=l;i++)
50         {
51             gets(dm);
52             int ldm=strlen(dm);
53             int x=0,y=0;
54             if(dm[0]=='E') nnn=0;
55             if(dm[0]!='E')
56             {
57                 ii[i]=dm[2];
58                 bool k=0,xn=0;
59                 for(int j=4;j<=ldm;j++)
60                 {
61                     if(dm[j]>='0'&&dm[j]<='9')
62                     {
63                         if(k==0) x=x*10+dm[j]-'0';
64                         else y=y*10+dm[j]-'0';
65                     }
66                     if(dm[j]==' ') k=1;
67                     if(x!=0&&k==1&&dm[j]=='n') {nnn++;break;}
68                     if(x==0&&k==0&&dm[j]=='n') {xn=1;break;}
69                 }
70                 if(x>y&&nn==0) dx=1;
71             }
72             nn=max(nn,nnn);
73         }
74         sort(ii+1,ii+1+l);
75         char iii=ii[1];
76             if(pn==1&&on==nn) printf("Yes\n");
77             if(pn==0&&on==1) printf("Yes\n");
78             if(pn==1&&on!=nn) printf("No\n"); 
79     }
80     return 0;
81 }
40分

待写出正解

D1T3 逛公园

先spfa跑一遍跑出最短路,然后再反向建图,跑dfs记忆化搜索

具体题解

我的20分淳朴dfs+spfaQAQ

 1 /*
 2 id:gww
 3 language:
 4 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊 
 5 */
 6 #include<bits/stdc++.h>
 7 using namespace std;
 8 const int N=100000+2;
 9 const int M=200000+2;
10 const int inf=0x3f3f3f3f;
11 int n,m,k,p,dis[N],s,ans=0;
12 int head[M],cnt=0;
13 bool vis[N];
14 int read()
15 {
16     int w=0,x=0;char ch=0;
17     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
18     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
19     return w?-x:x;
20 }
21  
22 struct lxyy
23 {
24     int u,v,w,nxt;
25 }e[M];
26 void add(int u,int v,int w)
27 {
28     e[++cnt].u=u;
29     e[cnt].v=v;
30     e[cnt].w=w;
31     e[cnt].nxt=head[u];
32     head[u]=cnt;
33 }
34 void clean()
35 {
36     ans=0;
37     memset(head,0,sizeof(head));
38     memset(vis,0,sizeof(vis));
39     memset(dis,inf,sizeof(dis));
40 }
41  
42 queue<int> q;
43 void spfa(int u)
44 {
45     q.push(u),dis[u]=0,vis[u]=1;
46     while(!q.empty())
47     {
48         u=q.front();
49         q.pop(),vis[u]=0;
50         for(int i=head[u];i!=0;i=e[i].nxt)
51         {
52             int v=e[i].v,w=e[i].w;
53             if(dis[v]>dis[u]+w)
54             {
55                 dis[v]=dis[u]+w;
56                 if(vis[v]==0)
57                 {
58                     q.push(v);
59                     vis[v]=1;
60                 }
61             }
62         }
63     }
64 }
65  
66 void dfs(int nw,int ti)
67 {
68     if(ti>s) return;
69     if(nw==n) {ans++;ans%=p;return;}
70     for(int i=head[nw];i!=0;i=e[i].nxt)
71     {
72         int v=e[i].v,w=e[i].w;
73         if(ti+w>s) continue;
74         dfs(v,ti+w);
75     }
76 }
77  
78 int main()
79 {
80     int t=read();
81     while(t--)
82     {
83         clean();
84         n=read(),m=read(),k=read(),p=read();
85         for(int i=1;i<=m;i++)
86         {
87             int u=read(),v=read(),w=read();
88             add(u,v,w);
89         }
90         spfa(1);s=dis[n]+k;
91         dfs(1,0);
92         printf("%d\n",ans%p);
93     }
94     return 0;
95 }
20分

spfa+反向建图跑dfs判断零环

  1 /*
  2 id:gww
  3 language:
  4 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊 
  5 */
  6 #include<bits/stdc++.h>
  7 using namespace std;
  8 const int N=100000+2;
  9 const int M=200000+2;
 10 const int inf=0x3f3f3f3f;
 11 int n,m,k,p,dis[N],s,ans=0;
 12 int head[M],cnt=0;
 13 int dp[N][52],in[N][52];//dp[i][k]表示比i-u最短路径多k有多少条 
 14 bool vis[N],fla;
 15 int read()
 16 {
 17     int w=0,x=0;char ch=0;
 18     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
 19     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
 20     return w?-x:x;
 21 }
 22  
 23 struct lxyy
 24 {
 25     int u,v,w,nxt;
 26 }e[M];
 27 void add(int u,int v,int w,int cnt)
 28 {
 29     e[cnt].u=u;
 30     e[cnt].v=v;
 31     e[cnt].w=w;
 32     e[cnt].nxt=head[u];
 33     head[u]=cnt;
 34 }
 35 void clean()
 36 {
 37     ans=0,fla=0;
 38     memset(head,0,sizeof(head));
 39     memset(vis,0,sizeof(vis));
 40     memset(dis,inf,sizeof(dis));
 41     memset(dp,0,sizeof(dp));
 42     memset(in,0,sizeof(in));
 43 }
 44  
 45 queue<int> q;
 46 void spfa()
 47 {
 48     q.push(1),dis[1]=0,vis[1]=1;
 49     while(!q.empty())
 50     {
 51         int u=q.front();
 52         q.pop(),vis[u]=0;
 53         for(int i=head[u];i!=0;i=e[i].nxt)
 54         {
 55             int v=e[i].v,w=e[i].w;
 56             if(dis[v]>dis[u]+w)
 57             {
 58                 dis[v]=dis[u]+w;
 59                 if(vis[v]==0)
 60                 {
 61                     vis[v]=1;
 62                     q.push(v);
 63                 }
 64             }
 65         }
 66     }
 67 }
 68  
 69 int dfs(int nw, int ti) 
 70 {
 71     if (in[nw][ti] == 1 || fla) return fla = 1; 
 72     if (in[nw][ti] == 2) return dp[nw][ti]; 
 73     in[nw][ti] = 1; //
 74     for (int i = head[nw]; i; i = e[i].nxt) 
 75     {
 76         int v=e[i].v;
 77         int w = ti+dis[nw]-dis[v]-e[i].w; 
 78         if (w>k||w<0) continue;
 79         dp[nw][ti]+=dfs(v, w);
 80         dp[nw][ti]%=p;
 81     }
 82     in[nw][ti]=2; //设置该点曾经访问过
 83     return dp[nw][ti]; //回溯答案
 84 }
 85  
 86 int main()
 87 {
 88     int t=read();
 89     while(t--)
 90     {
 91         clean();
 92         n=read(),m=read(),k=read(),p=read();
 93         for(int i=1;i<=m;i++)
 94         {
 95             int u=read(),v=read(),w=read();
 96             add(u,v,w,i);
 97         }
 98         spfa();
 99         memset(head,0,sizeof(head));
100         for(int i=1;i<=m;i++)//反向建图 可以对照着add来理解 
101         {
102             swap(e[i].u,e[i].v);
103             e[i].nxt=head[e[i].u];
104             head[e[i].u]=i;
105         }
106         dp[1][0]=1;
107         for(int i=0;i<=k;i++)
108         {
109             ans+=dfs(n,i);
110             ans%=p;
111         }
112         if(fla==1) printf("-1\n");
113         else printf("%d\n",ans%p);
114     }
115     return 0;
116 }
100昏

拓扑排序

D2T1奶酪

我用的搜索,从最下面那个连通奶酪开始搜(我忘了并查集了

最最最重要就是记得开long long分不清哪要开long long就全都开,我昨天打的时候忘了给快读加long longQAQ

 1 /*
 2 id:gww
 3 language:
 4 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
 5 */
 6 #include<bits/stdc++.h>
 7 using namespace std;
 8 #define ll long long
 9 const int N=1000+5;
10 ll n,h,r;
11 bool vis[N],ans;
12  
13 ll read()
14 {
15     ll x=0,w=0;char ch=0;
16     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
17     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
18     return w?-x:x;
19 }
20 struct lxyy
21 {
22     ll x,z,y;
23 }e[N];
24  
25 ll jud(ll x1,ll x2,ll y1,ll y2,ll z1,ll z2)
26 {
27     ll xx=x1-x2,yy=y1-y2,zz=z1-z2;
28     ll sum=xx*xx+yy*yy+zz*zz;
29     return sum;
30 }
31  
32 void dfs(ll x,ll y,ll z,int cnt)
33 {
34     if(z+r>=h)
35     {
36         ans=1;
37         return;
38     }
39     vis[cnt]=1;
40     for(int i=1;i<=n;i++)
41     if(vis[i]==0&&jud(x,e[i].x,y,e[i].y,z,e[i].z)<=4*r*r)
42     dfs(e[i].x,e[i].y,e[i].z,i);
43 }
44  
45 int main()
46 {
47     int t=read();
48     while(t--)
49     {
50         memset(vis,0,sizeof(vis));
51         ans=0;
52         n=read(),h=read(),r=read();
53         for(int i=1;i<=n;i++)
54         e[i].x=read(),e[i].y=read(),e[i].z=read();
55         for(int i=1;i<=n;i++)
56         {
57             if(ans==1) break;
58             if(r-e[i].z>=0)
59             dfs(e[i].x,e[i].y,e[i].z,i);
60         }
61         if(ans==1) printf("Yes\n");
62         else printf("No\n");
63     }
64     return 0;
65 }
View Code

D2T1 宝藏

看数据就可以看出来是状压dp,可是我太弱了 想不出来转移方程

作为一个蒟蒻肯定满脑子都是暴力暴力暴力暴力 我们就学过一个高大上(并不) 实用的算法—dfs

好吧是我昨天想了半天之后选择看题解,然后发现了dfs+状压,好理解又好写(最适合我这种蒟蒻了) 状压真的超级有趣

cnt[]表示到到起点的距离 dp[state]表示状态为state时的最少花费,然后就一个洞一个洞地打,找最优解

能跑过大概是因为dp状态的更新有条件

 1 /*
 2 id:gww
 3 language:
 4 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
 5 */
 6 #include<bits/stdc++.h>
 7 using namespace std;
 8 const int N=15;
 9 const int M=1000+5;
10 const int inf=0x3f3f3f3f;
11 int n,m,ans=inf,r[N][N];
12 int dp[1<<N],cnt[N];
13 
14 int read()
15 {
16     int w=0,x=0;char ch=0;
17     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
18     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
19     return w?-x:x;
20 }
21 
22 void startt()
23 {
24     n=read(),m=read();
25     for(int i=1;i<=n;i++)
26     for(int j=1;j<=n;j++)
27     r[i][j]=inf;//初始化
28     for(int i=1;i<=m;i++)
29     {
30         int x=read(),y=read(),w=read();
31         r[x][y]=r[y][x]=min(w,r[x][y]);
32     }
33 }
34 
35 void clean()
36 {
37     for(int i=1;i<=n;i++)
38     cnt[i]=inf;
39     for(int i=1;i<=(1<<n);i++)
40     dp[i]=inf;
41 }
42 
43 void dfs(int x)
44 {
45     for(int i=1;i<=n;i++)
46     if(x&(1<<(i-1)))//被开发过的宝藏屋 
47     {
48         for(int j=1;j<=n;j++)
49         if(!((1<<(j-1))&x)&&r[i][j]!=inf)//枚举相连的 未开发的宝藏屋 
50         {
51             int neww=x|(1<<(j-1));
52             if(dp[neww]>dp[x]+r[i][j]*cnt[i])
53             {
54                 int wa=cnt[j];
55                 dp[neww]=dp[x]+r[i][j]*cnt[i];
56                 cnt[j]=cnt[i]+1;
57                 dfs(neww);
58                 cnt[j]=wa;//回溯操作! 
59             }
60         }
61         
62     }
63 }
64 
65 int main()
66 {
67     startt();
68     for(int i=1;i<=n;i++)//枚举每一个洞
69     {
70         clean();
71         cnt[i]=1,dp[(1<<(i-1))]=0;
72         dfs(1<<(i-1));
73         ans=min(ans,dp[(1<<n)-1]);
74      } 
75      printf("%d",ans);
76     return 0;
77 }
View Code

D2T1 列队

(总是说成队列)

靠死想不出来这个,看题解看到线段树、splay、树状数组什么的,我选择死亡

其实暑假的时候线段树都没怎么消化(我懂了,我这就滚去练线段树)

我的30分模拟

 1 /*
 2 id:gww
 3 language:
 4 啊啊啊啊啊啊啊啊啊啊啊啊啊 
 5 */
 6 #include<bits/stdc++.h>
 7 using namespace std;
 8 const int N=1000+5;
 9 const int Q=500+5;
10 int n,m,q;
11 int las[N],h[N],pos[1005][1005];
12  
13 int read()
14 {
15     int x=0,w=0;char ch=0;
16     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
17     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
18     return w?-x:x;
19 }
20  
21 struct lxyy
22 {
23     int x,y;
24 }e[N];
25  
26 int main()
27 {
28     n=read(),m=read(),q=read();
29     for(int i=1;i<=q;i++)
30     {
31         e[i].x=read(),e[i].y=read();
32     }
33     for(int i=1;i<=n;i++)
34     for(int j=1;j<=m;j++)
35     pos[i][j]=(i-1)*m+j;
36     for(int i=1;i<=q;i++)
37     {
38         long long ans;
39         ans=(long long)pos[e[i].x][e[i].y];
40         printf("%lld\n",ans);
41         for(int j=e[i].y;j<=m-1;j++)//向左看齐
42         pos[e[i].x][j]=pos[e[i].x][j+1];
43         pos[e[i].x][m]=pos[e[i].x+1][m];
44         for(int j=e[i].x;j<n;j++)//向前看齐
45         pos[j][m]=pos[j+1][m];
46         pos[n][m]=ans;
47     } 
48     return 0;
49 }
30分

昨晚还看了一个50分的,然后自己理解着也写了差不多的,今天一考我就忘了50分这个怎么写,最后向模拟屈服

因为一次就出一个人,然后就只改变出去的当前行和最后一列 所以!我们就只用研究改变行和最后一列 然后就50昏!

 1 /*
 2 id:gww
 3 language:
 4 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊 
 5 */
 6 #include<bits/stdc++.h>
 7 using namespace std;
 8 #define ll long long
 9 const int N=50002;
10 int n,m,q,tot;
11 ll las[N],h[N],pos[501][N];
12 ll ans;
13 
14 int read()
15 {
16     int w=0,x=0;char ch=0;
17     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
18     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
19     return w?-x:x;
20 }
21 struct lxyy
22 {
23     int x,y;
24 }e[N];
25 
26 int main()
27 {
28     n=read();m=read();q=read();
29     for(int i=1;i<=q;i++)
30     {
31         e[i].x=read();e[i].y=read();
32         h[i]=e[i].x;//改变的横坐标
33     }
34     for(int i=1;i<=n;i++)
35     las[i]=las[i-1]+m;//最后一列编号 
36     sort(h+1,h+q+1);//去重之前要排序
37     tot=unique(h+1,h+q+1)-h-1;//去重之后原数组只剩下tot大小
38     ll t;
39     for(int i=1;i<=tot;i++)
40     {
41         t=(ll)(h[i]-1)*m;
42         for(int j=1;j<=m;j++)
43         pos[i][j]=++t;//给每一行每一列都标上号
44     }
45     int xx;
46     for(int i=1;i<=q;i++)
47     {
48         for(int j=1;j<=tot;j++)
49         if(h[j]==e[i].x)//寻找e[i].x在h数组中的位置
50         {nx=j;break;}
51         if(e[i].y==m)//如果出队的这个人在最后一列
52         ans=last[h[nx]];
53         else ans=pos[nx][e[i].y];
54         printf("%lld\n",ans);
55         if(e[i].y!=m)//向左看齐
56         {
57             for(int j=e[i].y;j<m-1;j++)
58             pos[nx][j]=pos[nx][j+1];
59             pos[nx][m-1]=last[h[nx]];
60         }
61         for(int j=h[nx];j<n;++j)//向前看齐
62         last[j]=last[j+1];
63         last[n]=ans;//归队 
64     }
65     return 0;
66 }
50分

 

QAQ等我什么时候会了满分的再添

还是我太弱了

 

posted @ 2019-01-22 17:08  委屈的咸鱼鱼鱼鱼  阅读(187)  评论(0编辑  收藏  举报