• APIO2018练习赛伪题解


    传送门:https://pcms.university.innopolis.ru/statements/org/apio/2018/practice/statements.pdf

    主要就在于后面三道构造题,感觉开阔了眼界。

    A:

    A + B problem,没看到实数还WA了一发

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=l; i<=r; i++)
     5 typedef long long ll;
     6 using namespace std;
     7 
     8 int main(){
     9     double a,b; scanf("%lf%lf",&a,&b); printf("%.4lf
    ",a+b);
    10     return 0;
    11 }

    B:

    翻转数组

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=l; i<=r; i++)
     5 typedef long long ll;
     6 using namespace std;
     7 
     8 const int N=20010;
     9 int n;
    10 ll a[N];
    11 
    12 int main(){
    13     scanf("%d",&n); rep(i,1,n) scanf("%lld",&a[i]);
    14     for (int i=n; i; i--) printf("%lld ",a[i]);
    15     return 0;
    16 }

    C:

    给定每个数的小数点后有效位数,确定每个小数,使和为1。

    所有数都取0.0...1,最后选一个位数最多的作为(1-其余的和),如果为负数则无解。

    有几种特殊情况要讨论一下,写一个假的高精度就好。

    手调几种情况都没有错,交上去爆零不懂为什么。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=l; i<=r; i++)
     5 typedef long long ll;
     6 using namespace std;
     7 
     8 const int N=200010;
     9 int n,mx,k,l,kk,a[N],d[N];
    10 
    11 bool add(int x){
    12     for (int i=x; i; i--){
    13         d[i]++; if (d[i]<=9) break; d[i]-=10;
    14     }
    15     if (d[1]>9) return 1; else return 0;
    16 }
    17 
    18 void sub(){ rep(i,1,mx-1) d[i]=9-d[i]; d[mx]=10-d[mx]; }
    19 
    20 int main(){
    21     freopen("c.in","r",stdin);
    22     freopen("c.out","w",stdout);
    23     scanf("%d",&n);
    24     if (n==1) { puts("NO"); return 0; }
    25     rep(i,1,n) scanf("%d",&a[i]),mx=max(mx,a[i]);
    26     rep(i,1,n) if (a[i]==mx) { k=i; break; }
    27     rep(i,1,n) if (a[i]==mx) l++;
    28     if (l==1){ puts("NO"); return 0; }
    29     if (l%10==1){ rep(i,1,n) if (a[i]==mx && i!=k) { kk=i; break; } add(mx);};
    30     rep(i,1,n) if (i!=k)
    31         if (add(a[i])) { puts("NO"); return 0; }
    32     sub(); puts("YES");
    33     rep(i,1,n) if (i!=k){
    34         printf("0."); rep(j,2,a[i]) printf("0");
    35         if (i==kk) puts("2"); else puts("1");
    36     }else{
    37         printf("0."); rep(j,1,mx) printf("%d",d[j]); puts("");
    38     }
    39     return 0;
    40 }

    D:

    铺地砖,每次可以把两块一起翻90度,构造初始状态到最终状态的方案。

    S和T都全部变成横的或竖的,然后把T的方案反过来输出就好了。不存在无解。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define rep(i,l,r) for (int i=l; i<=r; i++)
     4 using namespace std;
     5 
     6 const int N=52,K=100010;
     7 char s[N][N];
     8 int n,m,x[K],y[K],xn,cnt,t,k[260];
     9 
    10 void solve(){
    11     k[t]=0;
    12     rep(i,1,n){
    13         scanf("%s",s[i]+1);
    14         rep(j,1,m) k[s[i][j]]++;
    15     }
    16     while (k[t]){
    17         rep(i,1,n) rep(j,1,m)
    18             if (s[i][j]=='U' && s[i][j+1]=='U'){
    19                 x[++cnt]=i; y[cnt]=j;
    20                 s[i][j]=s[i+1][j]='L'; s[i][j+1]=s[i+1][j+1]='R';
    21                 k['U']-=2; k['L']+=2;
    22             }
    23         if (!k[t]) return;
    24        rep(i,1,n) rep(j,1,m)
    25             if (s[i][j]=='L' && s[i+1][j]=='L'){
    26                 x[++cnt]=i; y[cnt]=j;
    27                 s[i][j]=s[i][j+1]='U'; s[i+1][j]=s[i+1][j+1]='D';
    28                 k['U']+=2; k['L']-=2;
    29             }
    30     }
    31 }
    32 
    33 int main(){
    34     scanf("%d%d",&n,&m);
    35     t=(n&1) ? 'U' : 'L';
    36     solve(); xn=cnt; solve(); printf("%d
    ",cnt);
    37     rep(i,1,xn) printf("%d %d
    ",x[i],y[i]);
    38     for (int i=cnt; i>xn; i--) printf("%d %d
    ",x[i],y[i]);
    39     return 0;
    40 }

    E:

    每次将字符串任意分成两段,后半段翻转放前面,前半段直接放后面,构造S->T的方案,步数尽量少。

    据说这种构造转移类题目主要思想是在维护好已构造部分的同时扩大构造范围。

    3n做法:https://blog.csdn.net/qq_32506797/article/details/79377650

    5/2 n做法 和 2n做法 分别在官网tutorial和tutorial的讨论区里,还没看。

    下面是3n做法:

     1 #include<cstdio>
     2 #include<vector>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=l; i<=r; i++)
     5 using namespace std;
     6 
     7 const int N=2010;
     8 int n;
     9 char su[N], sv[N];
    10 vector<int> vec;
    11 
    12 void shift(int x){
    13     if (x==0) return;
    14     reverse(su+1,su+n+1); reverse(su+x+1,su+n+1);
    15     vec.push_back(x);
    16 }
    17 
    18 int main(){
    19     scanf("%d%*d",&n);
    20     scanf("%s", su+1); scanf("%s", sv+1);
    21     rep(i,1,n){
    22         int j=i; while (j<=n && su[j]!=sv[n-i+1]) j++;
    23         if (j==n+1) { puts("-1"); return 0; }
    24         shift(n); shift(j-1); shift(1);
    25     }
    26     printf("%d
    ",(int)vec.size());
    27     for (int i=0; i<vec.size(); i++) printf("%d ",vec[i]);
    28     puts("");
    29     return 0;
    30 }
  • 相关阅读:
    java常见排序算法选择排序、冒泡排序、插入排序分析与比较
    使用SqlBulkCopy批量插入或迁移数据(转)
    用ADO.Net实现Oracle大批量数据更新优化(转)
    MSSQL 查询优化(转)
    .net的dataset,datatable,object等对象转json方法
    VS2005中的水晶报表也可以用推模式动态绑定数据源
    web项目经理手册开发时间估算
    Ajax:拥抱JSON,让XML走开
    (转)我国IT行业“项目经理制”现状
    转:web项目经理手册风险管理
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9018395.html
Copyright © 2020-2023  润新知