标签:
A题(Win or Freeze)(博弈&数论):
数论知识补充:
算术基本定理:一个大于
解题思路:
1.考虑到q为1或质数是,显然a获胜,直接打印1,0。
2.然后考虑q的非本身的质因子个数:如果质因子个数大于等于3个,那表示其中任意两个质因子的乘积小于q,且为q的一个合数(质数只有它本身一个质因子)因子(根据算术基本定理易得),这种情况下a只需将q分解成任意两个质因子之积x(这里考虑到算术基本定理相逆的情况,确定的质数序列的乘积为唯一确定的一个数,且这个数的因子也必定是这些质数序列),那么b只能把x分解成两个质数之一,a必胜。
3.最后考虑q的非本身质数因子为2,那么这个数所有的因子就是这两个质因子【因为这两个数的乘积等于q,不可能有其它合数因子(一个数的合数因子,都是它的质数因子相乘得到的,而这个数的质数因子相乘只有得到它本身一个结果)】,无论a选那一个都是b稳赢。
心得:这个题看了半天,所有单词都查了,就是读不懂题意。然后赛后理解了题意也不知道怎么做,因为不知道算术基本定理。
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long int LL;
const int M=1009,INF=0x3ffffff;
bool isprime(LL x) {
for(LL i = 2; i * i <= x; i++) if(x % i == 0) return false;
return x > 1; //排除小于等于1的情况
}
int main(void) {
LL q;
scanf("%I64d", &q);
if(q == 1 && isprime) cout << "1" << endl << "0" << endl;
else {
int n = 0, f, s;
for(LL i = 2; i * i <= q; i++) {
if(q % i == 0) { //如果i是q的因子就看i是否是质数
q /= i;
if(n == 0){f = i; i--;}
if(n == 1) {s = i; i--;}
if(n == 2) break;
n++;
}
}
if(n == 2) cout << 1 << endl << s * f << endl;
else cout << 2 << endl;
}
return 0;
}
B题(Coderforces 148B)(模拟):
在纸上写好伪代码,考虑周全了,交上去,一次ac无它纯模拟。不要惧怕模拟题,只要仔细一次过是可以的。
代码:
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long int LL;
const int M=100009,INF=0x3fffffff;
double vp, vd, pp, pd, t, f, c;
int main(void) {
cin >> vp >> vd >> t >> f >> c;
if(vd <= vp) cout << "0" << endl;
else {
double x = ((t *vp)/(vd - vp)) * vd;
if(x >= c) cout << "0" << endl;
else {
int ans = 0;
while(true) {
ans++;
double d = ((x / vd) * 2 + f) * vp;
x = (d / (vd - vp)) * vp + x + d;
if(x >= c) {cout << ans << endl; break;}
}
}
}
return 0;
}
C题(贪心):
是一个均分问题,但是有人数最多相差一的限制,使其简单了。如果没有人数限制,就可转化为背包容量为总数一半的01背包来做,寻找最接近一半的值。
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long int LL;
const int M=100009,INF=0x3fffffff;
int n, str[M],a ,b;
pair<int, int> v[M];
int main(void) {
cin >> n;
for(int i = 0; i < n; i++){cin >> v[i].first; v[i].second = i + 1;}
sort(v, v + n);
int q = 0, p = n - 1, x = 0, y = 0;
while(p >= q) {
if(p == q) {
if(a <= b){str[v[p].second] = 1; x++;}
else y++;
break;
}
if(a >= b) {
a += v[q].first;
str[v[q].second] = 1;
b += v[p].first;
p--;
q++;
}
else {
b += v[q].first;
str[v[p].second] = 1;
a += v[p].first;
p--;
q++;
}
x++;
y++;
}
cout << x << endl;
bool ok = false;
for(int i = 1; i <= n; i++) {
if(str[i]) {
if(ok) cout << " ";
cout << i;
ok =true;
}
}
cout << endl;
cout << y << endl;
ok = false;
for(int i = 1; i <= n; i++) {
if(!str[i]) {
if(ok) cout << " ";
cout << i;
ok = true;
}
}
cout << endl;
return 0;
}
D题(coderforces154B):
至今未过过一阵子再来吧=-=
标签:
原文地址:http://blog.csdn.net/jibancanyang/article/details/45276611