首页 > 代码库 > Educational Codeforces Round 16

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 long21 #define lson l,m,rt<<122 #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 long21 #define lson l,m,rt<<122 #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\n",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 long21 #define lson l,m,rt<<122 #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             else54             {55                 printf("%d ",y);56                 y+=2;57             }58         printf("\n");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 long21 #define lson l,m,rt<<122 #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\n",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     else78     {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\n",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 long21 #define lson l,m,rt<<122 #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\n",f[n]);50 }
View Code

 

 

Problem F String Set Queries

Educational Codeforces Round 16