zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 16

    Problem A King Moves

    题目大意

      有一个国际象棋的棋盘,给定一个国王的位置,求其移动一步可到达的合法位置数量。

    解题分析

      国王的位置可以分为3类,每类的答案为8、5、3。

    参考程序

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <string>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <cstdlib>
    11 #include <cstring>
    12 #include <cassert>
    13 #include <iostream>
    14 #include <algorithm>
    15 #pragma comment(linker,"/STACK:102400000,102400000")
    16 using namespace std;
    17 
    18 #define N 508             
    19 #define M 50008    
    20 #define LL long long
    21 #define lson l,m,rt<<1
    22 #define rson m+1,r,rt<<1|1 
    23 #define clr(x,v) memset(x,v,sizeof(x));
    24 #define bitcnt(x) __builtin_popcount(x)
    25 #define rep(x,y,z) for (int x=y;x<=z;x++)
    26 #define repd(x,y,z) for (int x=y;x>=z;x--)
    27 const int mo  = 1000000007;
    28 const int inf = 0x3f3f3f3f;
    29 const int INF = 2000000000;
    30 /**************************************************************************/ 
    31 
    32 int main(){
    33     char c,n;
    34     scanf("%c%c",&c,&n);
    35     int num=0;
    36     if (c=='a' || c=='h') num++;
    37     if (n=='1' || n=='8') num++;
    38     if (num==0) puts("8");
    39     if (num==1) puts("5");
    40     if (num==2) puts("3");
    41 }
    View Code

    Problem B Optimal Point on a Line

    题目大意

      在一条直线上有n个点,求某个点使得其到其他点的距离之和最小。

    解题分析

      排序之后输出正中间的点即可。

    参考程序

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <string>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <cstdlib>
    11 #include <cstring>
    12 #include <cassert>
    13 #include <iostream>
    14 #include <algorithm>
    15 #pragma comment(linker,"/STACK:102400000,102400000")
    16 using namespace std;
    17 
    18 #define N 508             
    19 #define M 50008    
    20 #define LL long long
    21 #define lson l,m,rt<<1
    22 #define rson m+1,r,rt<<1|1 
    23 #define clr(x,v) memset(x,v,sizeof(x));
    24 #define bitcnt(x) __builtin_popcount(x)
    25 #define rep(x,y,z) for (int x=y;x<=z;x++)
    26 #define repd(x,y,z) for (int x=y;x>=z;x--)
    27 const int mo  = 1000000007;
    28 const int inf = 0x3f3f3f3f;
    29 const int INF = 2000000000;
    30 /**************************************************************************/ 
    31 int n; 
    32 int a[300008];
    33 int main(){
    34     scanf("%d",&n);
    35     rep(i,1,n) scanf("%d",&a[i]);
    36     sort(a+1,a+n+1);
    37     printf("%d
    ",a[(n+1)/2]);
    38 }
    View Code

    Problem C Magic Odd Square

    题目大意

      将1~n^2的数字填入n*n的矩形,使得每行每列每条正对角线的数字之和均为奇数。

      n <= 49 , 且n为奇数。

    解题分析

      通过观察样例和探索后可以发现一种合法的构造方案。

      在n*n的矩形正中间放置一个完全由奇数组成的旋转45度的(n-1)*(n-1)的矩形。

    参考程序

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <string>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <cstdlib>
    11 #include <cstring>
    12 #include <cassert>
    13 #include <iostream>
    14 #include <algorithm>
    15 #pragma comment(linker,"/STACK:102400000,102400000")
    16 using namespace std;
    17 
    18 #define N 508             
    19 #define M 50008    
    20 #define LL long long
    21 #define lson l,m,rt<<1
    22 #define rson m+1,r,rt<<1|1 
    23 #define clr(x,v) memset(x,v,sizeof(x));
    24 #define bitcnt(x) __builtin_popcount(x)
    25 #define rep(x,y,z) for (int x=y;x<=z;x++)
    26 #define repd(x,y,z) for (int x=y;x>=z;x--)
    27 const int mo  = 1000000007;
    28 const int inf = 0x3f3f3f3f;
    29 const int INF = 2000000000;
    30 /**************************************************************************/ 
    31 int n,x,y; 
    32 int a[108][108];
    33 int main(){
    34     scanf("%d",&n);
    35     int mid=(n+1)/2;
    36     rep(i,1,mid){
    37         rep(j,mid-i+1,mid+i-1)
    38             a[i][j]=1;
    39     }
    40     rep(i,1,mid-1){
    41         rep(j,mid-i+1,mid+i-1)
    42             a[n-i+1][j]=1;
    43     }
    44     x=1; y=2;
    45     rep(i,1,n)
    46     {
    47         rep(j,1,n)
    48             if (a[i][j]==1)
    49             {
    50                 printf("%d ",x);
    51                 x+=2;
    52             }
    53             else
    54             {
    55                 printf("%d ",y);
    56                 y+=2;
    57             }
    58         printf("
    ");
    59     }
    60 
    61 }
    View Code

    Problem D Two Arithmetic Progressions

    题目大意

      给定a1, b1, a2, b2, L, R (0 < a1, a2 ≤ 2·109,  - 2·109 ≤ b1, b2, L, R ≤ 2·109, L ≤ R)。

      求所有满足条件的x的数量,x=a1*k+b1=a2*l+b2,且 L≤x≤R。

    解题分析

      x=a1*k'+b1=a2*l'+b2

      移项后可得 a1*k-a2*l=b2-b1。

      用exgcd解出最小的k',l'。

      则k=k'+(a2/gcd(a1,a2))*m。

      由 k>=0 ,l>=0 和 L<=a1*k+b1<=R 解出m的范围。 

    参考程序

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <string>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <cstdlib>
    11 #include <cstring>
    12 #include <cassert>
    13 #include <iostream>
    14 #include <algorithm>
    15 #pragma comment(linker,"/STACK:102400000,102400000")
    16 using namespace std;
    17 
    18 #define N 508             
    19 #define M 50008    
    20 #define LL long long
    21 #define lson l,m,rt<<1
    22 #define rson m+1,r,rt<<1|1 
    23 #define clr(x,v) memset(x,v,sizeof(x));
    24 #define bitcnt(x) __builtin_popcount(x)
    25 #define rep(x,y,z) for (int x=y;x<=z;x++)
    26 #define repd(x,y,z) for (int x=y;x>=z;x--)
    27 const int mo  = 1000000007;
    28 const int inf = 0x3f3f3f3f;
    29 const LL INF = 20000000000000ll;
    30 /**************************************************************************/ 
    31 
    32 LL a1,b1,a2,b2,L,R,x,y,d;
    33 
    34 LL gcd(LL x,LL y){
    35     return y == 0 ? x : gcd(y,x % y);
    36 }
    37 
    38 LL exgcd(LL a,LL b,LL &x,LL &y){
    39     if (b==0){
    40         x=1;
    41         y=0;
    42         return a; 
    43     }
    44     LL d=exgcd(b,a%b,y,x);
    45     y-=x*(a/b);
    46     return d;
    47 }
    48 LL up(LL x,LL y){
    49     if (x>0) return x % y ? x / y + 1 : x / y;   
    50     return x / y;
    51 }
    52 LL down(LL x,LL y){
    53     if (x>0) return x / y;
    54     return x % y ? x / y - 1 : x / y;
    55 }
    56 int main(){
    57     scanf("%lld%lld%lld%lld%lld%lld",&a1,&b1,&a2,&b2,&L,&R);
    58     d=exgcd(a1,-a2,x,y);
    59     if ((b2-b1) % d!=0){
    60         printf("%d
    ",0);
    61         return 0;
    62     }
    63     LL k0 = x * (b2-b1) / d;
    64     k0 =(k0 % (a2/d) + (a2/d)) % (a2/d);
    65     LL l0 = (a1*k0+b1-b2) /a2;
    66 
    67    // cout << k0 << " " << l0 << endl;
    68     LL l,r,ll,lll,rr,rrr;
    69     if (d>0)
    70     {
    71         r = down((R-a1*k0-b1)*d,a1*a2);
    72         l = up((L-a1*k0-b1)*d,a1*a2);
    73         ll = up(-k0*d,a2);
    74         lll = up(-l0*d,a1);
    75         l=max(max(ll,lll),l);
    76     }
    77     else
    78     {
    79         l = up((R-a1*k0-b1)*d,a1*a2);
    80         r = down((L-a1*k0-b1)*d,a1*a2);
    81         rr = down(-k0*d,a2);
    82         rrr = down(-l0*d,a1);
    83         r=min(min(rr,rrr),r);    
    84 
    85         LL x1 = (R-a1*k0-b1)*d ; 
    86         LL x2 = (L-a1*k0-b1)*d ;
    87         LL y1 = a1 * a2;
    88         
    89     }
    90     printf("%lld
    ",r-l+1>0 ? r-l+1 : 0 );
    91 }
    View Code

    Problem E Generate a String

    题目大意

      每次操作可以花费x的代价将数字加1或减1,或者花费y的代价将数字乘2。

      求将数字从0变到数字n的最小代价。

      n<=10^7。

    解题分析

      可以发现一个显然的dp方程

        dp[i]=min{dp[i-1]+x,dp[i+1]+x,dp[i/2]+y(2|i)}

      由于n很大,不能高斯消元。

      经过思考后可以发现-1的操作不会连续执行两次(必然可以通过+1和*2来代替)。

      所以每次dp[i]时,顺便求出dp[i+1],再由dp[i+1]来更新dp[i]。  

    参考程序

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <string>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <cstdlib>
    11 #include <cstring>
    12 #include <cassert>
    13 #include <iostream>
    14 #include <algorithm>
    15 #pragma comment(linker,"/STACK:102400000,102400000")
    16 using namespace std;
    17 
    18 #define N 508             
    19 #define M 50008    
    20 #define LL long long
    21 #define lson l,m,rt<<1
    22 #define rson m+1,r,rt<<1|1 
    23 #define clr(x,v) memset(x,v,sizeof(x));
    24 #define bitcnt(x) __builtin_popcount(x)
    25 #define rep(x,y,z) for (int x=y;x<=z;x++)
    26 #define repd(x,y,z) for (int x=y;x>=z;x--)
    27 const int mo  = 1000000007;
    28 const int inf = 0x3f3f3f3f;
    29 const int INF = 2000000000;
    30 /**************************************************************************/ 
    31 
    32 LL f[10000008];
    33 
    34 int n,x,y;
    35 
    36 int main(){
    37     scanf("%d%d%d",&n,&x,&y);
    38     f[0]=0;
    39     rep(i,1,n){
    40         f[i]=f[i-1]+x;
    41         if (i % 2 == 0) f[i]=min(f[i],f[i/2]+y);
    42         
    43         f[i+1]=f[i]+x;
    44         if ((i+1) % 2==0) f[i+1]=min(f[i+1],f[(i+1)/2]+y);
    45 
    46         f[i]=min(f[i],f[i+1]+x);
    47 
    48     }
    49     printf("%I64d
    ",f[n]);
    50 }
    View Code

    Problem F String Set Queries

  • 相关阅读:
    [恢]hdu 2002
    [恢]hdu 2001
    [恢]hdu 2003
    [恢]hdu 1000
    ActionButton的处理流程 天龙packet
    ogre visibleflag
    Scaleform Gfx的Demo
    cegui 自定义控件
    PixWin
    在Ogre中加载自己的资源包
  • 原文地址:https://www.cnblogs.com/rpSebastian/p/5817570.html
Copyright © 2011-2022 走看看