您的位置:首页 > 其它

CF R334 div2

2015-12-02 11:17 351 查看
Codeforces R334 div2

过题数:1

A:

题意:模拟CF的算分机制

思路:简单计算签到

源码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int m[5];
int w[5];
int s1, s2;
while(scanf("%d", &m[0]) != EOF){
for(int i = 1 ; i < 5 ; i++)    scanf("%d", &m[i]);
for(int i = 0 ; i < 5 ; i++)    scanf("%d", &w[i]);
scanf("%d%d", &s1, &s2);
int ans = 0;
int x = 500;
for(int i = 0 ; i < 5 ; i++){
ans += max(x / 10 * 3, x - x / 250 * m[i] - 50 * w[i]);
x += 500;
}
ans += 100 * s1 - 50 * s2;
ans = max(ans, 0);
printf("%d\n", ans);
}
return 0;
}


B:

题意:把n个物品(<=1e5)分配到k个箱子里(2 * k <= 1e5),可以两个物品放在一个箱子里面。每个物品有体积(<=1e6),问需要的最大的箱子体积多少。

思路:贪心,先按照一个物品一个箱子分配知道2 * k == n,即箱子必须要放两个物品的时候。这时候对于此时剩下的最大物品,它取第一个物品即剩下的最小物品时对箱子体积要求最低。然后就完了。

源码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
const int MAXN = 100000 + 5;
int s[MAXN];
int main()
{
int n, k;
while(scanf("%d%d", &n, &k) != EOF){
for(int i = 1 ; i <= n ; i++)   scanf("%d", &s[i]);
if(n == 1){
printf("%d\n", s[1]);
continue;
}
int ans = 0;
while(k * 2 > n && n > 0){ ///现场没加n>0判断怒WA
ans = max(ans, s
);
n--;
k--;
}
int head = 1 ,rear = n;
while(head < rear){
ans = max(ans, s[head] + s[rear]);
head++, rear--;
}
printf("%d\n", ans);
}
return 0;
}


C:

题意:一段01串(len<=1e5)。现在有一种操作使得一串01串变成10串(即0->1,1->0),最多使用一次。问变换后能得到01串中,按顺序但不一定连续抽取0和1组成010101类似的串,这样串的最大长度多少。

思路:把原01串中连续的0和1看成一个带有权重的字符。这样原串就转化为一个标准的0101串。

然后分类讨论。如果有一个字符权重大于2,比如111,它就能给答案增加2比如变成101(多增0和1)。如果有两个及以上字符权重等于2,比如11010100,它可以这样转换1 010101 0,然后答案也可以增加2。最不济的情况是只有一个字符权重为2其余为1,则只能给答案增加1。Else 不进行任何操作。

具体构建模型可以用一个数轴来表示区间大小。

源码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int MAXN = 100000 + 5;
int len[MAXN], cnt;
char str[MAXN];
int main()
{
int n;
while(scanf("%d", &n) != EOF){
scanf("%s", str);
if(n == 1){
printf("1\n");
continue;
}
memset(len, 0, sizeof(len));
cnt = 1;
int pre = str[0] - '0';
len[cnt] = 1;
for(int i = 1 ; i < n ; i++){
if(str[i] - '0' == pre){
len[cnt]++;
}
else{
pre = str[i] - '0';
len[++cnt] = 1;
}
}
if(cnt == 1){
if(len[1] > 2)  printf("3\n");
else if(len[1] == 1)    printf("1\n");
else    printf("2\n");
continue;
}
int ans = cnt;
int ok1 = 0;
int flag = 0;
for(int i = 1 ; i <= cnt ; i++){
if(len[i] >= 2) ok1++;
if(len[i] > 2)  flag = 1;
}
if(ok1 >= 2 || flag)    ans += 2;
else if(ok1 == 1)   ans++;
printf("%d\n", ans);
}
return 0;
}


D:(赛中无思路)

题意:给一个函数f(k*x%p) = k*f(x)%p,现在数的范围为[0,p-1],问有几种分配f[i]的方式使得满足上面这个函数。

思路:

感谢并膜拜q巨orz~

由函数可知f(k*x%p)可以由f(x)推出,故可知它最终会构成一个环,即确定了f(x)的值,就可以推出其他和f(x)在同一个环上的值。

那么现在要找有几个环。设一个环的长度为r,则有k^r * x == x即k^r == 1(modp)。暴力查找就可以。

因为剩余不确定的数为p-1个(0这个数可由f(0) = k * f(0)推出恒为0)可用类似唯一分解定理的定理证明(p-1) % r = 0。

然后答案为p ^ ((p-1) / r))。

以上均假设k>2的情况(奇质数才有以上性质)。K=0和1特判。k为2的特判可以与k>2的情况合并所以就一起写了。

源码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
#define LL long long
#define inf (1000000007)
LL ppow(LL a, LL x, LL mod)
{
LL ans = 1;
while(x){
if(x & 1)   ans = (ans * a) % mod;
a = (a * a) % mod;
x >>= 1;
}
return ans;
}
int main()
{
LL n, k;
while(scanf("%I64d%I64d", &n, &k) != EOF){
LL ans = 0;
if(k == 0)  ans = ppow(n, n - 1, inf);
else if(k == 1){
ans = ppow(n, n, inf);
}
else{
LL r = 1;
for(int i = 2 ; i <= n ; i++){ ///此处不能从1开始
if(ppow(k, i, n) == 1){
r = i;
break;
}
}
ans = ppow(n, (n - 1) / r, inf);
}
printf("%I64d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: