• 【NOIp】NOIp2014


    NOIp 2014

    day 1 T1 生活大爆炸版石头剪刀布

    标签:模拟

    code(巨丑

     1 #include <iostream>
     2 #include <cstdio>
     3 using namespace std;
     4 int main(){
     5     int n,na,nb,x,y,xa[201],xb[201],i,j,a,ans,bns;
     6     cin>>n>>na>>nb;
     7     for(i=1;i<=na;i++){
     8         cin>>x;
     9         xa[i]=x;
    10     }
    11     for(j=1;j<=nb;j++){
    12         cin>>y;
    13         xb[j]=y;
    14     }
    15     ans=0;bns=0;
    16     i=0;j=0;
    17     for(a=1;a<=n;a++){
    18         i++;j++;
    19         if(i>na)i=1;
    20         if(j>nb)j=1;
    21         if(xa[i]==0&&xb[j]==1)bns++;
    22         if(xa[i]==0&&xb[j]==2)ans++;
    23         if(xa[i]==0&&xb[j]==3)ans++;
    24         if(xa[i]==0&&xb[j]==4)bns++;
    25         if(xa[i]==1&&xb[j]==0)ans++;
    26         if(xa[i]==1&&xb[j]==2)bns++;
    27         if(xa[i]==1&&xb[j]==3)ans++;
    28         if(xa[i]==1&&xb[j]==4)bns++;
    29         if(xa[i]==2&&xb[j]==0)bns++;
    30         if(xa[i]==2&&xb[j]==1)ans++;
    31         if(xa[i]==2&&xb[j]==3)bns++;
    32         if(xa[i]==2&&xb[j]==4)ans++;
    33         if(xa[i]==3&&xb[j]==0)bns++;
    34         if(xa[i]==3&&xb[j]==1)bns++;
    35         if(xa[i]==3&&xb[j]==2)ans++;
    36         if(xa[i]==3&&xb[j]==4)ans++;
    37         if(xa[i]==4&&xb[j]==0)ans++;
    38         if(xa[i]==4&&xb[j]==1)ans++;
    39         if(xa[i]==4&&xb[j]==2)bns++;
    40         if(xa[i]==4&&xb[j]==3)bns++;
    41     }
    42     cout<<ans<<" "<<bns;
    43     return 0;
    44 }
    T1

    day 1 T2 联合权值

    标签:dp

    转化:

    step 1: 无向图,n个点,n-1条边 => 一棵树

    step 2: 距离为2 => 和同一个点相连

    枚举每一个点,取任意两点组合得到乘积最大值和sum

    对于一个点,线性扫过所有与他相连的点,然后动态更新目前的和与目前这些点中的最大值

    再到下一个点时,将下一个点的权值与这两个值相乘

    code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 namespace gengyf{
     4 #define int long long
     5   inline int read(){
     6     int x=0,f=1;char s=getchar();
     7     while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
     8     while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
     9     return f*x;
    10   }
    11   const int mod=10007;
    12   const int maxn=2e5+10;
    13   struct edge{
    14     int nxt,to;
    15   }e[maxn*2];
    16   int head[maxn],cnt,n,w[maxn];
    17   inline void add(int from,int to){
    18     e[++cnt].to=to;e[cnt].nxt=head[from];head[from]=cnt;
    19   }
    20   int ans,maxx;
    21   int main(){
    22     n=read();
    23     for(int i=1;i<n;i++){
    24       int u,v;
    25       u=read();v=read();
    26       add(u,v);add(v,u);
    27     }
    28     for(int i=1;i<=n;i++){
    29       w[i]=read();
    30     }
    31     for(int i=1;i<=n;i++){
    32       int max1=0,max2=0,t1=0,t2=0;
    33       for(int j=head[i];j;j=e[j].nxt){
    34         if(w[e[j].to]>max1){
    35           max2=max1;max1=w[e[j].to];
    36         }
    37         else if(w[e[j].to]>max2)max2=w[e[j].to];
    38         t1=(t1+w[e[j].to])%mod;
    39         t2=(t2+w[e[j].to]*w[e[j].to])%mod;
    40       }
    41       t1=t1*t1%mod;
    42       ans=(ans+t1-t2+mod)%mod;
    43       if(maxx<max1*max2)maxx=max1*max2;
    44     }
    45     printf("%lld %lld",maxx,ans);
    46     return 0;
    47   }
    48 }
    49 signed main(){
    50   gengyf::main();
    51   return 0;
    52 }
    T2

    day 1 T3 飞扬的小鸟

    标签:dp

    上升 -> 完全背包  单位时间上升是可以叠加的

    下降 -> 01背包 单位时间只能下降1次

    转移:

    <1>上升

    <2>飞到顶上

    <3>下降

    <4>有柱子

    上升:$f[i][j]=min(f[i][j],min(f[i-1][j-lift[i-1],f[i][j-lift[i-1]])+1)$

    code

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define MAXN 1<<30
     4 struct Pipe{
     5     int pos,up,bottom;
     6 }pipe[10010];
     7 int n,m,k,lift[10010],down[10010],f[10010][1010];
     8 bool cmp(Pipe a,Pipe b){
     9     return a.pos<b.pos;
    10 }
    11 int main(){
    12     scanf("%d%d%d",&n,&m,&k);
    13     for(int i=0;i<=n-1;i++){
    14         scanf("%d%d",&lift[i],&down[i]);
    15     }
    16     for(int i=1;i<=k;i++){
    17         scanf("%d%d%d",&pipe[i].pos,&pipe[i].bottom,&pipe[i].up); 
    18     }
    19     sort(pipe+1,pipe+k+1,cmp);
    20     for(int i=0;i<=n;i++)
    21         for(int j=0;j<=m;j++){
    22             f[i][j]=MAXN;
    23         }
    24     for(int i=1;i<=m;i++)f[0][i]=0;
    25     int nump=1;
    26     for(int i=1;i<=n;i++){
    27         int lower=1,upper=m;
    28         if(pipe[nump].pos==i){
    29             upper=pipe[nump].up-1;
    30             lower=pipe[nump++].bottom+1; 
    31         }
    32         for(int j=1;j<=upper;j++){
    33             for(int k=j-lift[i-1];k<=m;k++){
    34                 if(k>j-lift[i-1]&&j<m)break;
    35                 if(k>=1)f[i][j]=min(f[i][j],min(f[i-1][k],f[i][k])+1);
    36             }
    37         }
    38         for(int j=lower;j<=upper;j++){
    39             if(j+down[i-1]<=m){
    40                 f[i][j]=min(f[i][j],f[i-1][j+down[i-1]]);
    41             }
    42         }
    43         for(int j=1;j<=lower-1;j++)f[i][j]=MAXN;
    44     }
    45     int minn=MAXN;
    46     bool flag=false;
    47     for(int i=n;i>=1;i--){
    48         for(int j=1;j<=m;j++){
    49             if(f[i][j]!=MAXN){
    50                 flag=true;
    51                 minn=min(minn,f[i][j]);
    52             }
    53         }
    54         if(flag){
    55             if(i==n){
    56                 printf("1
    %d",minn); 
    57                 return 0;
    58             }
    59             else{
    60                 for(int j=k;j>=1;j--){
    61                     if(i>=pipe[j].pos){
    62                         printf("0
    %d",j);
    63                         return 0;
    64                     }
    65                 }
    66             }
    67         }
    68     }
    69     printf("0
    0");
    70     return 0;
    71 }
    T3

    day 2 T1 无线网络发射器选址

    标签:模拟,二维前缀和

    枚举每一个点,更新最大值+统计答案个数

    code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 namespace gengyf{
     4 #define ll long long
     5   inline int read(){
     6     int x=0,f=1;char s=getchar();
     7     while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
     8     while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
     9     return f*x;
    10   }
    11   int a[130][130],n,d,s[130][130],ans,cnt;
    12   int main(){
    13     d=read();n=read();
    14     for(int i=1;i<=n;i++){
    15       int x,y,num;
    16       x=read();y=read();num=read();
    17       a[x][y]=num;
    18     }
    19     for(int i=0;i<=128;i++)
    20       for(int j=0;j<=128;j++){
    21         s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
    22       }
    23     for(int i=0;i<=128;i++)
    24       for(int j=0;j<=128;j++){
    25         int x1,x2,y1,y2;
    26         x1=max(i-d,0);y1=max(j-d,0);
    27         x2=min(i+d,128);y2=min(j+d,128);
    28         int tmp=s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1];
    29         if(tmp==ans)cnt++;
    30         else if(tmp>ans){
    31           cnt=1;ans=tmp;
    32         }
    33       }
    34     printf("%d %d",cnt,ans);
    35     return 0;
    36   }
    37 }
    38 signed main(){
    39   gengyf::main();
    40   return 0;
    41 }
    T4

    day 2 T2 寻找道路

    标签:图论,最短路

    对于要求1可以反向建图dfs标记能到终点的点

    如果标记的点,如果它的出边有未被标记的,则不合法,取消标记

    对于要求2在标记的点中跑最短路

    code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 namespace gengyf{
     4 #define ll long long
     5 inline int read(){
     6     int x=0,f=1;char s=getchar();
     7     while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
     8     while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
     9     return f*x;
    10 }
    11 const int maxn=1e4+10;
    12 vector<int>G[maxn];
    13 queue<int>q;
    14 bool v[maxn],vis[maxn];
    15 int n,m,ans[maxn],s,t;
    16 int main(){
    17     n=read();m=read();
    18     for(int i=1;i<=m;i++){
    19         int a,b;a=read();b=read();
    20         if(a==b)continue;
    21         G[b].push_back(a);
    22     }
    23     s=read();t=read();
    24     v[t]=1;q.push(t);
    25     while(!q.empty()){
    26         int x=q.front();
    27         q.pop();
    28         for(int i=0;i<G[x].size();i++){
    29             if(!v[G[x][i]]){
    30                 v[G[x][i]]=1;
    31                 q.push(G[x][i]);
    32             }
    33         }
    34     }
    35     memcpy(vis,v,sizeof(v));
    36     for(int i=1;i<=n;i++){
    37         if(!v[i]){
    38             for(int j=0;j<G[i].size();j++){
    39                 if(vis[G[i][j]])vis[G[i][j]]=0;
    40             }
    41         }
    42     }
    43     q.push(t);
    44     while(!q.empty()){
    45         int x=q.front();
    46         q.pop();
    47         for(int i=0;i<G[x].size();i++){
    48             if(vis[G[x][i]]){
    49                 q.push(G[x][i]);
    50                 vis[G[x][i]]=0;
    51                 ans[G[x][i]]=ans[x]+1;
    52             }
    53         }
    54     }
    55     if(ans[s]==0)puts("-1");
    56     else printf("%d",ans[s]);
    57     return 0;
    58 }
    59 }
    60 signed main(){
    61   gengyf::main();
    62   return 0;
    63 }
    T5

    day 2 T3 解方程

    标签:数学

    秦九韶算法  O(n)

    枚举[1,m]代入函数f(x)看是否为0,注意取模

    code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 namespace gengyf{
     4 #define ll long long
     5 const int p=1e9+7;
     6 const int maxn=1e6+10;
     7 inline ll read(){
     8     ll x=0,f=1;
     9     char c=getchar();
    10     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    11     while(c>='0'&&c<='9'){x=((x*10)+c-'0')%p;c=getchar();}
    12     return x*f;
    13 }
    14 ll sum,a[110],n,m,ans[maxn],cnt;
    15 bool t=1;
    16 bool calc(ll x){
    17     sum=0;
    18     for(ll i=n;i>=1;i--){
    19         sum=((a[i]+sum)*x)%p;
    20     }
    21     sum=(sum+a[0])%p;
    22     return !sum;
    23 }
    24 int main(){
    25     n=read();
    26     m=read();
    27     for(ll i=0;i<=n;i++){
    28         a[i]=read();
    29     }
    30     for(ll i=1;i<=m;i++){
    31         if(calc(i)){
    32             t=false;
    33             cnt++;
    34             ans[cnt]=i;
    35         }
    36     }
    37     if(t){
    38         cout<<cnt<<endl;
    39         return 0;
    40     }
    41     printf("%lld
    ",cnt);
    42     for(int i=1;i<=cnt;i++){
    43         printf("%lld
    ",ans[i]);
    44     }
    45     return 0;
    46 }
    47 }
    48 signed main(){
    49   gengyf::main();
    50   return 0;
    51 }
    T6

    4102年的题真友好 

  • 相关阅读:
    C# winform开发:Graphics、pictureBox同时画多个矩形
    C# “配置系统未能初始化” 异常解决
    Google Maps API V3 之 路线服务
    Google Maps API V3 之 图层
    Google Maps API V3 之绘图库 信息窗口
    Google 地图 API V3 之 叠加层
    驱动开发之libusb函数
    libusb的使用教程和例子
    libusb检测U盘插入
    使用libusb检测USB设备插拔状态
  • 原文地址:https://www.cnblogs.com/gengyf/p/11573558.html
Copyright © 2020-2023  润新知