zoukankan      html  css  js  c++  java
  • 【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
    ");
    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
    ");
    77             if(pn==0&&on==1) printf("Yes
    ");
    78             if(pn==1&&on!=nn) printf("No
    "); 
    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
    ",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
    ");
    113         else printf("%d
    ",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
    ");
    62         else printf("No
    ");
    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
    ",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
    ",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等我什么时候会了满分的再添

    还是我太弱了

  • 相关阅读:
    Pull Request
    选择器
    常见HTTP状态码
    286. Walls and Gates
    200. Number of Islands
    1. Two Sum
    名片管理系统(python实现)
    k近邻算法(简单版)
    基数排序
    递归算法的调试
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/10304838.html
Copyright © 2011-2022 走看看