您的位置:首页 > 其它

COCI2015/2016 CONTEST#4 简易题解

2015-12-23 21:15 218 查看
T1:YODA

题意:给出两个数,要求把两个数对撞,每一个十进制位上的大的留在原数,如果相同,两个都留在原数,最后输出两个对撞后的原数。

思路:直接模拟即可,两个数每一次都/10%10,比较是否合法。

#include<cstdio>
#include<cstring>
char s1[20], s2[20];
int main() {
scanf("%s%s", s1, s2);
int N = strlen(s1), M = strlen(s2);
for(int i = N-1, j = M-1; i >= 0 && j >= 0; -- i, -- j) {
if(s1[i] > s2[j]) s2[j] = 0;
else if(s1[i] < s2[j]) s1[i] = 0;
}
int n = -1, m = -1;
for(int i = 0; i < N; ++ i)
if(s1[i]) {
if(n == -1) n = 0;
n = n * 10 + s1[i] - '0';
}
for(int i = 0; i < M; ++ i)
if(s2[i]) {
if(m == -1) m = 0;
m = m * 10 + s2[i] - '0';
}
if(n == -1) puts("YODA");
else printf("%d\n", n);
if(m == -1) puts("YODA");
else printf("%d\n", m);
return 0;
}


T2:HAN

题意:恶心模拟

思路:步数%26并作出相应操作。

#include<cstdio>
#include<algorithm>
using namespace std;
#define LL long long
int n, f, cur, st;
int cnt[30];
char c;
inline void GET(int &n) {
do c = getchar(); while('0' > c || c > '9'); n = 0;
while('0' <= c && c <= '9') {n = n*10+c-'0'; c = getchar();}
}
int main () {
int t1, t2; f = 1; cur = 0;
char op[10];
GET(n);
for(int i = 1; i <= n; ++ i) {
scanf("%s", op);
if(op[0] == 'S') {
GET(t1);
if(t1 - st >= 26) while(cur) { cur = ((cur + f) % 26 + 26) % 26, ++ st; ++ cnt[cur];}
for(int i = 0; i < 26; ++ i) cnt[i] += (t1 - st) / 26;
st += (t1 - st)/26*26;
for(; st < t1; ++ st) {
cur = ((cur + f) % 26 + 26) % 26;
++ cnt[cur];
}
f *= -1; st = t1;
}
else {
GET(t1); scanf("%s", op); t2 = (op[0] - 'a' + 1)%26;
if(t1 - st >= 26) while(cur) { cur = ((cur + f) % 26 + 26) % 26, ++ st; ++ cnt[cur];}
for(int i = 0; i < 26; ++ i) cnt[i] += (t1 - st) / 26; st += (t1 - st)/26*26;
for(; st < t1; ++ st) {
cur = ((cur + f) % 26 + 26) % 26;
++ cnt[cur];
}
st = t1;
printf("%d\n", cnt[t2]);
}
}
return 0;
}


T3:DEATHSTAR

题意:给你一个矩阵 第(i,j)表示Ai&Aj (&表示按位与(bitwise and))求数列{An}

思路:想想或运算,你知道了吗?

#include<cstdio>
int a[1005][1005], n;
int arr[1005];
char c;
inline void GET(int &n) {
do c = getchar(); while('0' > c || c > '9'); n = 0;
while('0' <= c && c <= '9') {n = n*10+c-'0'; c = getchar();}
}
int main () {
GET(n);
for(int i = 1; i <= n; ++ i)
for(int j = 1; j <= n; ++ j) {
GET(a[i][j]);
arr[i] |= a[i][j];
arr[j] |= a[i][j];
}
printf("%d", arr[1]);
for(int i = 2; i <= n; ++ i)
printf(" %d", arr[i]);
return 0;
}


T4:HEWBACCA

题意:给你一个完全K叉树,求两点间的距离。

思路:因为是完全K叉数,那么暴力爬树就是完全没有问题的了(1叉树需要特判)。

#include<cstdio>
#include<algorithm>
using namespace std;
#define LL long long
long long p[100], n, m, k, q;
char c;
inline void GET(LL &n) {
do c = getchar(); while('0' > c || c > '9'); n = 0;
while('0' <= c && c <= '9') {n = n*10+c-'0'; c = getchar();}
}
LL fa(LL x) {
int t = lower_bound(p+1, p+q+1, x) - p;
LL o = x - p[t-1];
o = (o+k-1)/k;
return p[t-2]+o;
}
int dep(LL x) {
return lower_bound(p, p+q+1, x) - p;   //其实这里可以直接写 "return x;"。因为编号适合深度有关的……我当时SB了
}
int main () {
GET(n); GET(k); GET(m);
p[2] = 1; LL t1, t2;
if(k != 1) {
for(q = 3; n / p[q-1] > k; ++ q) p[q] = p[q-1] * k;
for(int i = 1; i <= q; ++ i) p[i] += p[i-1];
p[q] = n;
}
for(int i = 1; i <= m; ++ i) {
int tot = 0;
GET(t1); GET(t2);
if(t1 > t2) swap(t1, t2);
if(k == 1) printf("%I64d\n", t2 - t1);
else {
while(t1 != t2) {
if(dep(t1) < dep(t2)) swap(t1, t2);
t1 = fa(t1); ++ tot;
}
printf("%d\n", tot);
}
}
return 0;
}


暂时到这里了,我并不知道T5、T6怎么做……等官方题解吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: