Codeforces Round #230 (Div. 2) 题解

A.Nineteen

题意:给你一堆字母,问最多组成的串中,最多有多少个子串是nineteen

思路:直接统计个数,注意nineteenineteen是两个

代码:

#include <bits/stdc++.h>
using namespace std;

char a[105];

int main()
{
  scanf("%s", a + 1);
  int len = strlen(a + 1);
  int cntn = 0, cnti = 0, cnte = 0, cntt = 0;
  for(int i = 1; i <= len; i++) {
    if(a[i] == 'n')cntn++;
    if(a[i] == 'i')cnti++;
    if(a[i] == 'e')cnte++;
    if(a[i] == 't')cntt++;
  }
  int ans = 0;
  cntn -= 3; cnti -= 1; cnte -=3; cntt -= 1;
  if(cntn < 0 || cnti < 0 || cnte < 0 || cntt < 0) {
    cntn = 0; cnti = 0; cnte = 0; cntt = 0;
  }
  else ans ++;
  // printf("test cntn == %d cnti == %d cnte == %d cntt == %d\n",cntn, cnti, cnte, cntt);
  int as = min(cntn / 2, cnti);
  as = min(as, min(cnte / 3, cntt));
  ans += as;
  cout << ans << endl;
  return 0;
}
View Code

B. Three matrices

    题意:给一个矩阵c,让构造出一个矩阵a和矩阵b,使的c = a + b,并且矩阵a中a[i][j] = a[j][i],矩阵b 中b[i][j] = - b[j][i]

    思路:对角线上可以让矩阵a直接等于c,让b矩阵的值为0,其他位置可以让a[i][j]与a[j][i]的值解出ab矩阵的值

    代码:

#include <bits/stdc++.h>
using namespace std;

const int maxn = 200;

double mp[maxn][maxn];
double ansa[maxn][maxn], ansb[maxn][maxn];

int main()
{
  int n;
  scanf("%d", &n);
  for(int i = 1; i <= n; i++) {
    for(int j = 1; j <= n; j++) {
      scanf("%lf", &mp[i][j]);
    }
  }
  for(int i = 1; i <= n; i++) {
    for(int j = 1; j <= i; j++) {
      if(i == j) {
        ansa[i][j] = mp[i][j];
        ansb[i][j] = 0;
      }
      else {
        ansa[i][j] = (mp[i][j] + mp[j][i]) / 2.0;
        ansa[j][i] = ansa[i][j];

        ansb[i][j] = fabs(mp[i][j] - mp[j][i]) / 2.0;
        ansb[j][i] = -1.0 * ansb[i][j];
        if(mp[i][j] < mp[j][i])swap(ansb[i][j], ansb[j][i]);
      }
    }
  }
  for(int i = 1; i <= n; i++) {
    for(int j = 1; j <= n; j++) {
      if(j > 1)printf(" ");
      printf("%f",ansa[i][j]);
    }
    puts("");
  }
  for(int i = 1; i <= n; i++) {
    for(int j = 1; j <= n; j++) {
      if(j > 1) printf(" ");
      printf("%f",ansb[i][j]);
    }
    puts("");
  }
  return 0;
}
View Code

C. Blocked Points

    题意:给你一个半径为n(4e7)的圆,问也有多少个点到圆的距离小于1

    思路:直接把每一个i(0~n)都枚举一下,每次维护前一个位置的值

    代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
  long long n;
  scanf("%lld", &n);
  if(n == 0) {
    printf("1\n");
    return 0;
  }
  long long ans = 0;
  long long pre = 0;
  for(long long i = 0; i <= n; i++) {
    long long as = (long long)(sqrt(1.0*(n*n-i*i)));
    ans ++;
    if(pre - as > 1) ans += pre - as - 1;
    pre = as;
  }
  ans --;
  cout << ans * 4 << endl;
  return 0;
}
View Code

D. Tower of Hanoi

    题意:汉诺塔问题,有一个3*3的矩阵a,a[i][j]表示从第i个柱子移动到第j个柱子的代价,问把k个盘子移到第3个柱子上最少需要多少代价

思路:定义dp[k][i][j]表示k个盘子从第i个柱子移动到第j个柱子的最小代价是多少,每次都有两种情况转移一种是k-1移动到2,然后k到3,然后2-》3,第二种是先移动到3,k到2,然后3到1,2到3,1到3

代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
int a[5][5];
LL dp[45][5][5];

int main()
{
  for(int i = 1; i <= 3; i++) {
    for(int j = 1; j <= 3; j++) {
      scanf("%d", &a[i][j]);
    }
  }
  int n;
  scanf("%d", &n);
  for(int k = 1; k <= n; k++) {
    for(int i = 1; i <= 3; i++) {
      for(int j = 1; j <= 3; j++) {
        if(i != j) {
          LL as = dp[k - 1][i][6 - i - j] + a[i][j] + dp[k - 1][6 - i -j][j];
          LL qw = dp[k - 1][i][j] + a[i][6 - i - j] + dp[k - 1][j][i] + a[6 - i - j][j] + dp[k - 1][i][j];
          dp[k][i][j] = min (as, qw);
        }
      }
    }
  }
  cout << dp[n][1][3] << endl;
  return 0;
}
View Code

E. Yet Another Number Sequence

    题意:定义sn表示∑(1~n)Fi * (i^k),Fi表示斐波那契数列,对1e9+7取模

    思路:拆成sn = sn-1 + (fn-1 * (n –1 + 1)^k ) + (fn-2 * (n – 2 + 2) ^k,然后矩阵快速幂

    代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int MOD = 1e9 + 7;
///使用前要先对r,c赋值
struct mat{
    long long a[90][90];
    int r,c;
    mat operator *(const mat &b)const{
        mat ret;
        for (int i=0;i<r;i++){
            for (int j=0;j<b.c;j++){
                ret.a[i][j]=0;
                for (int k=0;k<c;k++)
                    ret.a[i][j]+=a[i][k]*b.a[k][j],ret.a[i][j]%=MOD;
            }
        }
        ret.r=r;
        ret.c=b.c;
        return ret;
    }
    void init_unit(int x)
    {
        r=c=x;
        for(int i=0;i<r;i++){
            for(int j=0;j<c;j++){
                if(i==j)a[i][j]=1;
                else a[i][j]=0;
            }
        }
    }
}unit;
mat qmod(mat p,LL n){
    unit.init_unit(p.c);
    mat ans=unit;
    while(n){
        if(n&1)ans=p*ans;
        p=p*p;
        n>>=1;
    }
    return ans;
}
int k;
LL n,c[45][45];
void init()
{
  memset(c, 0, sizeof(c));
  c[0][0] = 1;
  for(int i = 1; i <= 40; i++) {
    c[i][0] = c[i][i] = 1;
    for(int j = 1; j < i; j++) {
      c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % MOD;
    }
  }
}
mat A,B;

int main()
{
  init();
  while(~scanf("%lld%d", &n, &k)) {
    if(n == 1) printf("1\n");
    else {
      A.r = A.c =2 * k + 3;
      memset(A.a, 0, sizeof(A.a));
      memset(B.a, 0, sizeof(B.a));
      A.a[0][0] = A.a[0][k + 1] = 1;
      for(int i = 0; i <= k; i++) {
        for(int j = 0; j <= i; j++) {
          A.a[i + 1][j + 1] = c[i][j];
          A.a[i + 1][j + k + 2] = (1LL << (i - j)) % MOD * c[i][j] %MOD;
        }
      }
      for(int i = k + 2; i <= 2 * k + 2; i++)
        A.a[i][i - (k + 1)] = 1;
      B.r = 2 * k + 3; B.c = 1;
      B.a[0][0] = 1;
      for(int i = 1; i <= k + 1; i++)
        B.a[i][0] = (1LL << i) % MOD;
      for(int i = k + 2; i <= 2 * k + 2; i++) 
        B.a[i][0] = 1;
      A = qmod(A, n - 2);
      A = A * B;
      printf("%lld\n", (A.a[0][0] + A.a[k + 1][0]) % MOD);
    }
  }
  return 0;
}
View Code

 

posted @ 2019-03-07 18:25  啦啦啦天啦噜  阅读(207)  评论(0编辑  收藏  举报