本渣清明节 闲里偷忙 做了一下codejam
水平不出意外的在投稿之后一落千丈
后两题的hidden test竟然都挂了
A. Foregone Solution
水题,稍微判断一下特殊情况(比如1000, 5000这种)就好了
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
B. You Can Go Your Own Way
水题,直接和她反着来就好了
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
C. Cryptopangrams
大家都知道求下相邻的数的gcd,然后去重,排序
有个小坑就是,序列当中可能相邻的数是相同的,也就意味着有原始密码有a,b,a这种。需要找到一个相邻的数不相同的,然后反推其他的所有
其次就是大数,c++模版不好找,不如写java, python
import java.io.*;
import java.util.*;
import java.math.*;
public class Solution {
Scanner in = new Scanner(new BufferedInputStream(System.in));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
BigInteger seq[] = new BigInteger[105];
BigInteger prime[] = new BigInteger[105];
// BigInteger num[] = new BigInteger[105];
int lower_bound(BigInteger[] nums, int begin, int end, BigInteger value) {
while (begin < end) {
int mid = begin + (end - begin) / 2;
if (nums[mid].compareTo(value) == -1) {
begin = mid + 1;
} else {
end = mid;
}
}
return begin;
}
void solve() {
int casNum;
casNum = in.nextInt();
for(int cas = 1; cas <= casNum; ++cas) {
BigInteger n;
int l;
n = in.nextBigInteger(); l = in.nextInt();
for(int i = 0; i < l; ++i) {
seq[i] = in.nextBigInteger();
}
int pos = -1;
for(int i = 1; i < l; ++i) {
if(seq[i].equals(seq[i-1]) == false) {
prime[i] = seq[i].gcd(seq[i-1]);
pos = i;
break;
}
}
for(int i = pos - 1; i >= 0; --i) {
prime[i] = seq[i].divide(prime[i + 1]);
}
for(int i = pos + 1; i <= l; ++i) {
prime[i] = seq[i-1].divide(prime[i-1]);
}
List num=new ArrayList<>();
for(int i = 0; i <= l; ++i) {
num.add(prime[i]);
}
Set uniqueGas = new HashSet(num);
// out.println(uniqueGas.size());
// for(BigInteger i : uniqueGas) {
// out.println(i);
// }
BigInteger[] result = uniqueGas.toArray(new BigInteger[0]);
Arrays.sort(result, 0, uniqueGas.size());
assert(uniqueGas.size() == 26);
// printf("%d\n", (int)num.size());
// for(int i = 0, len = num.size(); i < len; ++i) printf("%lld ", num[i]); printf("\n");
out.printf("Case #%d: ", cas);
for(int i = 0; i <= l; ++i) {
int tt = lower_bound(result,0, uniqueGas.size(), prime[i]);
out.printf("%c", tt + 'A');
}
out.printf("\n");
}
out.flush();
}
public static void main(String args[]) {
new Solution ().solve();
}
}
D. Dat Bae
如果B没有小于等于15的限制的话,本渣觉得需要10次查询,这也是本渣的解法
不断二分01查询,比如0011, 0101这样查,就能最后判断出来每个位置在不在
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
但是如果只是5次查询,这样不行。反过来通过1,2,4,8为界的查询方式,判断一个16个数的组的borken情况。
如下所示
0101010101010101
0011001100110011
0000111100001111
0000000011111111
可以每16个数一个组,因为我们知道最多15个broken,每组必会有数保留,那么我们就可以判断出每个数是在哪个组当中的。贴下别人的代码
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include