Codeforces Round #419 (Div. 2)

题目链接:http://codeforces.com/contest/816

A Karen and Morning

It is currently hh:mm, given in a 24-hour format. As you know, Karen loves palindromes, and she believes that it is good luck to wake up when the time is a palindrome.

What is the minimum number of minutes she should sleep, such that, when she wakes up, the time is a palindrome?

Remember that a palindrome is a string that reads the same forwards and backwards. For instance, 05:39 is not a palindrome, because 05:39 backwards is 93:50. On the other hand, 05:50 is a palindrome, because 05:50 backwards is 05:50.

过几分钟回文。

#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

bool check(int hour,int min){
    int t1=hour/10;
    int t2=hour%10;
    int t3=min/10;
    int t4=min%10;
    if(t1!=t4) return 0;
    if(t2!=t3) return 0;
    return 1;
}

int main(){
    int hour,min;
    scanf("%d:%d",&hour,&min);
    if(check(hour,min)){
        puts("0");
        return 0;
    }
    for(int i=1;;i++){
        min++;
        if(min==60){
            hour++;
            min=0;
        }
        if(hour==24){
            hour=0;
        }
        if(check(hour,min)){
            printf("%d\n",i);
            return 0;
        }
    } 
    return 0;
} 

B Karen and Coffee

Karen, a coffee aficionado, wants to know the optimal temperature for brewing the perfect cup of coffee. Indeed, she has spent some time reading several recipe books, including the universally acclaimed “The Art of the Covfefe”.

She knows n coffee recipes. The i-th recipe suggests that coffee should be brewed between li and ri degrees, inclusive, to achieve the optimal taste.

Karen thinks that a temperature is admissible if at least k recipes recommend it.

Karen has a rather fickle mind, and so she asks q questions. In each question, given that she only wants to prepare coffee with a temperature between a and b, inclusive, can you tell her how many admissible integer temperatures fall within the range?

n个菜单,每个菜单在[l,r]区间是好的。
统计[L,R]区间 菜单是好的的个数 >=k 的点。
对于[l,r]
presum[l]++
presum[r+1]–
然后求前缀和的时候就相当于presum[l..r]++了
前缀和统计+树状数组。

#include <bits/stdc++.h>

using namespace std;

const int maxn = 200000;

int presum[200005],n,k,q,l,r;

int A[maxn*4];

int lowbit(int x){
    return x&(-x); 
}

void add(int id){
    while(id<=maxn){
        A[id]++;
        id+=lowbit(id);
    }
}

int ask(int id){
    int sum=0;
    while(id){
        sum+=A[id];
        id-=lowbit(id); 
    }
    return sum;
}

int main(){
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout); 
    scanf("%d%d%d",&n,&k,&q);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&l,&r);
        presum[l]++;
        presum[r+1]--;
    }
    for(int i=1;i<=maxn;i++)
        presum[i]+=presum[i-1];
    for(int i=1;i<=maxn;i++)
        if(presum[i]>=k)
            add(i);
    for(int i=1;i<=q;i++){
        scanf("%d%d",&l,&r);
        int sum = ask(r) - ask(l-1);
        printf("%d\n",sum);
    }
    return 0;
}

C Karen and Game

The game is played as follows. In each level, you have a grid with n rows and m columns. Each cell originally contains the number 0.

One move consists of choosing one row or column, and adding 1 to all of the cells in that row or column.

To win the level, after all the moves, the number in the cell at the i-th row and j-th column should be equal to gi, j.

Karen is stuck on one level, and wants to know a way to beat this level using the minimum number of moves. Please, help her with this

类似消消乐吧。
直接贪心消除。
注意最小这个条件。
于是需要选择先消列还是行。
先消效益高的,就是数值小的那一个。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 150;
int g[maxn][maxn];
int minr[maxn],minc[maxn];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int n,m;
    cin>>n>>m;
    memset(minr,63,sizeof minr);
    memset(minc,63,sizeof minc);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>g[i][j];
    int sum=0;
    if(n<=m){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++) minr[i]=min(minr[i],g[i][j]);
            sum+=minr[i];
            for(int j=1;j<=m;j++) g[i][j]-=minr[i];
        }
        for(int j=1;j<=m;j++){
            for(int i=1;i<=n;i++) minc[j]=min(minc[j],g[i][j]);
            sum+=minc[j];
            for(int i=1;i<=n;i++) g[i][j]-=minc[j];
        }
    }
    else{
        for(int j=1;j<=m;j++){
            for(int i=1;i<=n;i++) minc[j]=min(minc[j],g[i][j]);
            sum+=minc[j];
            for(int i=1;i<=n;i++) g[i][j]-=minc[j];
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++) minr[i]=min(minr[i],g[i][j]);
            sum+=minr[i];
            for(int j=1;j<=m;j++) g[i][j]-=minr[i];
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++) if(g[i][j]){
            puts("-1");
            return 0;
        }
    }
    cout<<sum<<endl;
    for(int i=1;i<=n;i++) if(minr[i]){
        for(int k=1;k<=minr[i];k++) cout<<"row "<<i<<endl;
    }
    for(int i=1;i<=m;i++) if(minc[i]){
        for(int k=1;k<=minc[i];k++) cout<<"col "<<i<<endl;
    }
    return 0;
}

D Karen and Test

There are n integers written on a row. Karen must alternately add and subtract each pair of adjacent integers, and write down the sums or differences on the next row. She must repeat this process on the values on the next row, and so on, until only one integer remains. The first operation should be addition.

Note that, if she ended the previous row by adding the integers, she should start the next row by subtracting, and vice versa.

The teachers will simply look at the last integer, and then if it is correct, Karen gets a perfect score, otherwise, she gets a zero for the test.

Karen has studied well for this test, but she is scared that she might make a mistake somewhere and it will cause her final answer to be wrong. If the process is followed, what number can she expect to be written on the last row?

Since this number can be quite large, output only the non-negative remainder after dividing it by 1e9 + 7.

考虑最简版本每个ai对最终式子的贡献,可以令ai的系数为1,其余为0,类似0,0,0…1…0,0,0,同时暂且不考虑减法,可以得出每个ai的贡献为Ck−1n−1,然后通过下面这个过程,可以看出最终的式子,是两个奇偶序列和(最简版本),相加或做差得到的,n mod 4 = 2时相加,n mod 4 = 0时做差。(如果n是奇数,那么先暴力进行第一次变换使得n成为偶数)

#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const ll maxn = 200000+5;
ll fac[maxn], inv[maxn];//fac[i] 保存阶乘,inv[i] 保存fac[i]的逆元
ll a[maxn];
ll ans;
int n;
void add(ll &a, ll b){
    a += b;
    if(a >= mod) a -= mod;
}
//快速幂
ll pow_mod(ll a, ll p){
    ll ans = 1;
    while(p){
        if(p & 1) ans = ans * a % mod;
        a = a * a % mod;
        p >>= 1;
    }
    return ans;
}

//组合计算公式
ll C(int n, int k){
    return (fac[n] * inv[k] % mod )* inv[n-k] % mod;
}

int main(){
//freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    fac[0] = 1;
    for(int i = 1; i < maxn; i++) fac[i] = fac[i-1] * i % mod;
    inv[maxn-1] = pow_mod(fac[maxn-1],mod-2);
    for(int i = maxn - 2; i >=0; i--) inv[i] = inv[i+1] * (i+1) % mod;
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    if(n&1){
        if(n == 1) {cout << a[1] << endl; return 0;}
        int sign = 1;
        for(int i = 1; i < n; i++){
            a[i] = (a[i]+sign*a[i+1] + mod) %mod;
            sign*=-1;
        }
        n--;
    }
    ll sum1 = 0LL, sum2 = 0LL;
    for(int i = 1; i <= n; i++){
        if(i&1) add(sum1, C(n/2-1, i/2) * a[i]%mod);
        else add(sum2, C(n/2-1, i/2-1) * a[i]%mod);
    }
    if(n%4 != 0) cout << (sum1 + sum2) % mod << endl;
    else cout << (sum1 - sum2 + mod) % mod << endl;
    return 0;
}
posted @ 2018-03-16 08:51  foreignbill  阅读(108)  评论(0)    收藏  举报