题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6655

题目


QQ和CC两个人玩牌,QQ先出牌,数字标记牌上的颜色,每个人不能出另一个人出过的牌,但是可以出自己出过的牌,若轮到某人出牌,但是某人手里没牌了或者不能出牌了,那么那个人就输了。问最后的赢家是谁。

样例t, QQ手里n≤1e5张牌,CC手里m≤1e5张牌,p=1是给出每个人手里的牌对应的数字<2^64(要用unsigned long long), p=2用程序生成每个人手里的牌对应的数字。n+m不超过1e7

解题思路:


suma:QQ能出的牌数,sumb:CC能出的牌数

对每个人统计每张牌的牌数,对于自己有但对方没有的牌,肯定是可以全部出掉的,加入对应的suma/sumb中。

找出双方都有的牌,若对于牌i,QQ有张,CC有张,组成pair, 对pair按照+从大到小排序,统计QQ和CC分别能出的牌数。

给出的标准题解如下:

我想是让+越大, 那么有都相对比较大,两者不仅大而且很均衡,因为对于i不知道是轮到A拿还是轮到B拿,要让无论谁拿拿到的收益都比较大才比较公平吧,这才是最优策略。当然不排除一些极端情况。

ac代码:


unordered_map也这么慢吗,还是我哪里写的很慢。。。1900ms左右,在超时的边缘徘徊?

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
typedef unsigned long long ll;
typedef unordered_map<ll, ll> MAP;
typedef pair<ll, ll> PAIR;
ll k1, k2, mod, x, suma, sumb, cnt1, cnt2, cnt3;
ll A[maxn], B[maxn];
PAIR same[maxn];
int t, n, m, p;
ll rng() {unsigned long long k3 = k1, k4 = k2;k1 = k4;k3 ^= k3 << 23;k2 = k3 ^ k4 ^ (k3 >> 17) ^ (k4 >> 26);return k2 + k4;
}
void getArray(int p, MAP &a, MAP &b) // a,b 记录出现次数
{MAP vis1, vis2;if(p == 1){for(int i = 0; i < n; i++){scanf("%llu", &x);a[x]++;if(vis1[x] == 0) vis1[x] = 1, A[cnt1++] = x;}for(int i = 0; i < m; i++){scanf("%llu", &x);b[x]++;if(vis2[x] == 0)vis2[x] = 1, B[cnt2++] = x;}}else{scanf("%llu %llu %llu", &k1, &k2, &mod);for(int i = 0; i < n; i++){x = rng() % mod;a[x]++;if(vis1[x] == 0) vis1[x] = 1, A[cnt1++] = x;}scanf("%llu %llu %llu", &k1, &k2, &mod);for(int i = 0; i < m; i++){x = rng() % mod;b[x]++;if(vis2[x] == 0) vis2[x] = 1, B[cnt2++] = x;}}
}
bool cmp(PAIR a, PAIR b)
{return a.first + a.second > b.first + b.second;
}
int main()
{//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);scanf("%d", &t);while(t--){MAP a, b;cnt1 = cnt2 = cnt3 = 0;scanf("%d %d %d", &n, &m, &p);suma = n, sumb = m;getArray(p, a, b);for(int i = 0; i < cnt1; i++)if(b[A[i]]){same[cnt3++] = {a[A[i]], b[A[i]]};suma -= a[A[i]], sumb -= b[A[i]];}sort(same, same + cnt3, cmp);for(int i = 0; i < cnt3; i++){if(i % 2 == 0) suma += same[i].first;else sumb += same[i].second;}if(suma > sumb) printf("Cuber QQ\n");else printf("Quber CC\n");}return 0;
}

附上一个800ms左右的代码,它没有直接记录每个数出现的次数,一个for循环专门统计了出现的次数,而且只用了pair。ORZ

博客地址https://blog.csdn.net/qq_41117236/article/details/99442068

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int N=2e5+10;
P A[N],B[N],C[N];
ULL a[N];
ULL k1,k2;
ULL rng(){ULL k3=k1,k4=k2;k1=k4;k3^=k3<<23;k2=k3^k4^(k3>>17)^(k4>>26);return k2+k4;
}
void init(P T[],int& n,int p)
{if(p==1){for(int i=0;i<n;i++) scanf("%llu",&a[i]);}else{int mod; scanf("%llu%llu%d",&k1,&k2,&mod);for(int i=0;i<n;i++) a[i]=rng()%mod;}sort(a,a+n);int l=0;for(int i=0,j=0;i<n;i=j){while(j<n&&a[j]==a[i]) j++;T[l++]=P(a[i],j-i);}n=l;
}
bool cmp(const P& a, const P& b)
{return a.first+a.second>b.first+b.second;
}
int main()
{int T; scanf("%d",&T);while(T--){int n,m,p; scanf("%d%d%d",&n,&m,&p);init(A,n,p); init(B,m,p);int SA=0,SB=0,k=0;int p1=0,p2=0;while(p1<n||p2<m){if(p1<n&&p2<m&&A[p1].first==B[p2].first) C[k++]=P(A[p1++].second,B[p2++].second); //双方手里的相同颜色的牌的数目else if(p1==n||(p2<m&&A[p1].first>B[p2].first)) SB+=B[p2++].second; //如果B[p2].first比较小,那么说明不可能有相同颜色了else if(p2==m||(p1<n&&A[p1].first<B[p2].first)) SA+=A[p1++].second; //同上,所以直接加上贡献,这是互不影响的}sort(C,C+k,cmp); //按照贡献和排序for(int i=0;i<k;i++){if(i%2==0) SA+=C[i].first;else SB+=C[i].second;}if(SA>SB) puts("Cuber QQ"); //Cuber QQ 先手else puts("Quber CC");}return 0;
}

【2019杭电多校第七场1010=HDU6655】Just Repeat(思维)相关推荐

  1. 2019杭电多校 第七场 Kejin Player 6656(求期望值)

    2019杭电多校 第七场 Kejin Player 6656(求期望值) 题目 http://acm.hdu.edu.cn/showproblem.php?pid=6656 题意 给你n,q.表示有n ...

  2. 2019杭电多校第七场 HDU - 6656 Kejin Player 期望

    题目链接:https://vjudge.net/problem/HDU-6656 题解: 维护一个前缀sum[i] : 从1到 i 的期望 第 i 到达 i + 1是:ai + (1 - r[i] / ...

  3. 2019杭电多校第七场 HDU - 6656 Kejin Player——概率期望

    题意 总共有 $n$ 层楼,在第 $i$ 层花费 $a_i$ 的代价,有 $pi$ 的概率到 $i+1$ 层,否则到 $x_i$($x_i \leq 1$) 层.接下来有 $q$ 次询问,每次询问 $ ...

  4. 2019杭电多校第七场 Kejin Player HDU - 6656 (期望)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6656 题意:一种游戏,从i级升到i+1级,需要氪金a[i]RMB,有的概率成功,有1-的概率变成x[i ...

  5. 杭电多校第七场 1011 Kejin Player HDU(6656)

    杭电多校第七场 1011 Kejin Player 题意:给你N行,代表从i级有花费a[i]元的r[i]/s[i]的概率达到i+1级,剩下的概率中可能会到达x[i]级.然后询问从L级到R级的花费会是多 ...

  6. 2019杭电多校第9场1002 Rikka with Cake HDU6681

    2019杭电多校第9场1002 Rikka with Cake HDU6681 题意:给你若干个点按上下左右切割平面,最后问平面内有几块被切割开来. 解法1:红黑树+思维+贪心 A:根据欧拉定理可以得 ...

  7. 【2019.08.21】2019杭电多校第十场

    补题地址:http://acm.hdu.edu.cn/listproblem.php?vol=58 题号:6691-6701 1001: 1002: 1003:✅ 1004: 1005:✅ 1006: ...

  8. 2019 杭电多校第六场 题解

    比赛记录 注意随机数据 ,1-n排列这种,一般都有啥暴力重构之类的方法,期望重构次数很少之类的 1005也是这样,因为n^2但只有n个值有数,所以就可以n^2logn 题解 1001 Salty Fi ...

  9. 2019杭电多校第三场 6608 Fansblog(威尔逊定理+miller_rabin素性测试)

    Problem Description 传送门 Farmer John keeps a website called 'FansBlog' .Everyday , there are many peo ...

  10. 2019 杭电 多校第3场 1006 Fansblog (HDU 6608)

    题目链接 题解: 用威尔逊定理变换,然后求逆元. 代码: #include <bits/stdc++.h> using namespace std; typedef long long l ...

最新文章

  1. JS 中settimeout和setinterval函数的区别
  2. 正则表达式之?、(?:pattern)、(?!pattern)、(?=pattern)理解及应用
  3. 用命令行编译java并生成可执行的jar包
  4. SQL点点滴滴_UPDATE小计
  5. Redis的设计与实现之整数集合和压缩列表
  6. 第30课 棋盘上的学问 《小学生C++趣味编程》
  7. Callable 和 Future接口 学习
  8. Docker学习总结(63)——容器并不能解决一切问题
  9. Flickr.net傻瓜教程(三)--打造自己的图片搜索引擎
  10. WebStorm上vue模板设置
  11. 【1+X】软件测试用例概述
  12. 无线网络共享有线计算机,win10怎么把有线网络变成无线_win10如何共享有线网络为无线热点...
  13. SCAU软件开发基础C++复习
  14. 【最全】latex与word之间的各种转化方法和软件汇总
  15. foxmail 163企业邮箱配置
  16. trinity运行原理及常见报错(二)
  17. Java如何获取token
  18. 23.5 MySQL架构
  19. 自由幻想系统不能提供服务器,系统指南-自由幻想召集令-QQ自由幻想官方网站...
  20. 西式快餐是否比起肯德基更多人喜欢麦当劳,如果是原因是什么

热门文章

  1. yum mysql安装 日志_yum 安装与使用MySQL
  2. Oracle 查看表空间使用率,表空间扩展
  3. JUC主要包含哪些功能?
  4. IE兼容性问题web.config设置
  5. 阿里云容器服务Kubernetes之Jenkins X(2)-自动化CICD实践篇
  6. 金融数据获取的api接口
  7. MySQLl数据量不一样,导致走不同的索引
  8. win7设置固定IP重启后无法上网,ipconfig显示为自动配置IPV4 169.254的地址
  9. OEL修改字符集失败 -bash: /root: is a directory
  10. 开发小技巧: 如何在jQuery中禁用或者启用滚动事件.scroll