zoukankan      html  css  js  c++  java
  • [NOIP补坑计划]NOIP2013 题解&做题心得

    场上预计得分: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.搜索姿势水平要提高。

  • 相关阅读:
    用grunt搭建自动化的web前端开发环境-完整教程
    SQL Server:触发器详解
    利用junit对springMVC的Controller进行测试
    jquery-barcode:js实现的条码打印
    16个良好的 Bootstrap Angularjs 管理后台主题
    Spring Security 4 Hello World Annotation+XML
    intellij 13新建javaweb项目并用tomcat 7启动
    JavaScript类和继承:constructor属性
    javascript 的面相对象
    javascript call apply bind caller callee 的用法
  • 原文地址:https://www.cnblogs.com/dcdcbigbig/p/9863160.html
Copyright © 2011-2022 走看看