Codeforces Round #166 (Div. 2)

没有AK真是sad。。。

A  Beautiful Year

题意

给一个四位数y(1000 <= y <= 9000) 求第一个比y大的每一位都不同的数(尼玛怎么这么绕。。。)

解法:

这题目真是水的不行。。。直接暴力。 1min 过掉还是很爽的

Code:

int x;
bool use[10];
bool check(int y){
    RST(use);
    while(y){
        if(use[y%10]) return false;
        use[y %10] = 1;
        y /= 10;
    }
    return true;
}
void solve(){
    x++;
    while(!check(x)) x++;
    OT(x);
}
int main(){
    while(cin >>x) solve();

}

B  Prime Matrix

题意:

给一个N * M 的矩阵,每次可以给一个格子 + 1 , 要求某行 或者 某列都是质数,求最少操作次数。

解法:

暴力筛出1 ~ 1e5 + 3 (100003是质数)然后暴力。

Code:

const int N = 1000;
int a[N][N];
SI hash;
SI :: iterator iter;
int n , m;
void solve(){
    REP_2(i , j , n , m) {
        RD(a[i][j]);
        iter = hash.lower_bound(a[i][j]);
        a[i][j] = *iter - a[i][j];
    }
    int ans = INF;
    REP(i , n){
        int now = 0;
        REP(j , m) now += a[i][j];
        checkMin(ans , now);
    }
    REP(i , m){
        int now = 0;
        REP(j , n) now += a[j][i];
        checkMin(ans , now);
    }
    OT(ans);
}
int main(){
    getPrime();
    hash.clear();
    REP_1(i , prime[0]){
        hash.insert(prime[i]);
    }
    while(cin >> n >>m) solve();

}

For More:

如果每次的操作是把一行或者一列+1呢?

C  Secret

题意:

n个数(1 - n)分成k堆,每堆至少三个数,要求不能是等差数列。求一种构造。

解法:

乱搞,最简单的肯定是 1-k k-1 1-k 1 1 1 1  1
我的解法是 1-k k 1-(k-1) 1-k 1 1 1 1 1...

Code:

const int N = 1e6 + 9;
int a[N] , n , k;
void solve(){
    if (k * 3 > n){
        puts("-1");
        return;
    }
    RST(a);
    int head = 0;
    REP_1(i , k){
        a[head++] = i;
    }
    REP_1(i , k){
        int now = i + 1;
        if (now == k + 1) now = 1;
        a[head++] = now;
    }
    REP_1(i , k - 1){
        a[head++] = i;
    }
    REP(i , n){
        if (i) printf(" ");
        if (a[i] == 0) printf("%d", k);
        else printf("%d" , a[i]);
    }
    puts("");

}
int main(){
    while(cin >> n >> k) solve();
}

D  Good Substrings

题意:

给一个最大长度是1500的字符串,问有多少个不同的子串能满足某些字母出现次数 <= k

解法:

暴力枚举 + 字符串暴力hash。一开始竟然挂了。。

Code:

string str , v;
int k;
set<ULL> hash;
int main(){
    cin >> str >> v >> k;
    hash.clear();
    int len = str.length();
    REP_C(i , len){
        int bad = 0;
        ULL now = 0;
        FOR(j , i , len){
            bad += v[str[j] - 'a'] == '0';
            if (bad > k) break;
            now = now * 27 + str[j];
            hash.insert(now);
        }
    }
    OT(SZ(hash));
}
刚看到了能卡掉字典序hash的blog,Mark:http://hi.baidu.com/sillycross/item/386b1e172389391fb98a1ab1

神数据:

eoyirpkwgpvvwzaaaaaaaaaaaaaa
11111111111111111111111111
1

E  Three Horses

题意:

给n个数,和上限m。代表有n张牌正反面分别是(1 , a[i])有三种操作:
1、(a,b)  -> (a + 1 , b + 1)
2、 a、b都是偶数 (a / 2 , b / 2)
3、(a , b) , (b , c) -> (a , c)
求能构造的(x , y) (x,y <= m)有多少个

解法:

观察 牌的差可以发现,操作1 差不变,操作2可以把差翻倍,操作3可以把差加减。于是乎只用枚举出GCD(a[i] - 1) 所有的,枚举约数那么所有的差就是约数的2^k倍

Code:

VI divs;
int n , m;
int main(){
    RD(n , m);
    int d = 0;
    DO(n) d = GCD(RD() - 1 , d);
    for(int i = 1 ; i * i <= d ; ++i){
        if (d % i == 0){
            divs.PB(i);
            if (i * i != d) divs.PB(d / i);
        }
    }
    LL ans = 0;
    ECH(it , divs)
        if ((*it) & 1)
            for(int i = 0 ; ((LL)(*it) << i) < m ; ++i)
                ans += m - ((LL)(*it) << i);
    OT(ans);
}


你可能感兴趣的:(Codeforces Round #166 (Div. 2))