zoukankan      html  css  js  c++  java
  • 洛谷 P2348 题解

    本题解同步于我的洛谷博客

    本题思路:模拟。

    首先我们容易发现,因为每位玩家至少需要 (4) 张牌,所以如果 (k < n imes4),那么输出无解。

    然后我们可以看出,这道题的主要部分是在洗牌上。

    于是我们观察洗牌后的顺序:

    b[1] = a[k / 2 + 1];
    b[2] = a[1];
    b[3] = a[k / 2 + 2];
    b[4] = a[2];
    ...
    b[k - 1] = a[k];
    b[k] = a[k / 2];
    //其中 b 为洗牌后牌的花色,a 为洗牌前牌的花色
    

    可以看出(其中 a 为洗牌前牌的花色,b 为洗牌后牌的花色):

    [b_i = a_{frac{k}{2} + lceil {frac{i}{2}} ceil} (i mod 2 == 1) ]

    [b_i = a_{frac{i}{2}} (i mod 2==0) ]

    所以,我们就可以模拟 (m) 次洗牌,然后再 (O(k)) 发牌。

    时间复杂度为 (O(mk))

    AC 代码:

    #include <iostream>
    #include <cstdlib>
    #include <string>
    #include <cstdio>
    using namespace std;
    int n, k, m, p;
    struct sgs {
    	string a, b;
    } c[100010], d[100010];
    int main() {
    	cin >> n >> k >> m >> p;
    	if(k < n * 4) puts("Error:cards not enough"), exit(0); //判断无解情况
    	for(int i = 1; i <= k; i ++) cin >> c[i].a >> c[i].b;
    	for(int i = 1; i <= m; i ++) {
    		for(int j = 2; j <= k; j += 2) { //模拟洗牌过程
    			d[j].a = c[j / 2].a;
    			d[j].b = c[j / 2].b;
    			d[j - 1].a = c[k / 2 + j / 2].a;
    			d[j - 1].b = c[k / 2 + j / 2].b;
    		}
    		for(int j = 1; j <= k; j ++) c[j] = d[j]; //每次洗完牌要更新原数组
    	}
    	for(int i = 1, tot = 0; i <= k, tot < 4; i ++) { //模拟出牌过程
    		if((i - 1) % n + 1 == p) {
    			cout << d[i].a << ' ' << d[i].b << endl;
    			++ tot;
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    绑定下拉列表
    部署WSP出现错误—已在此服务器场中安装ID为XXXXX的功能
    sharepoint权限
    sql日期操作
    Sql脚本动态创建表
    sharepoint中添加子网站
    解决未知的服务器标记“asp:ListView”。
    sharepoint中新添加页面
    vue中使用localStorage存储信息
    Js事件大全
  • 原文地址:https://www.cnblogs.com/crp-cpp/p/13887252.html
Copyright © 2011-2022 走看看