• CDZSC_2022寒假个人训练赛21级(6)题解


    • 简单
      • C
      • E
      • F
    • 中等
      • B 博弈论、栈
      • E 贪心
    • 困难
      • A 模拟+优先队列(小根堆)
      • D dfs

    A Heap Operations CodeForces - 681C

    题意

    有个堆,有三种操作

    • insert x — 把x加到堆里。
    • getMin x — 得到堆里的最小值,且最小值等于x,当堆为空或者最小值不等于x时操作违法。
    • removeMin — 删除堆里的最小值,当堆为空时操作违法。
      题目给出了一些操作,不一定合法,往里再添加一些操作使得所有的操作都合法,求添加操作最少的情况并按序输出全部操作(新添加的和已存在的)。

    题解

    优先队列模拟操作

    • 当前操作为insert x时向队列中加入x
    • 当前操作为removeMin时将队列的top()删除,若队列为空则在removeMin前先insert一个在x的定义域内的任意值就好了
    • 当前操作为getMin x时:
      • 如果队列为空,则先insert x
      • 如果队列不为空,removeMin 掉所有比x小的,在此之后若top()大于x或队列为空,则insert x

    AC代码

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<ctime>
    #include<string>
    #include<vector>
    #include<map>
    #include<list>
    #include<set>
    #include<stack>
    
    #include<bitset>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<ll, ll> pii;
    typedef pair<ll, ll> pll;
    const ll N = 2e5 + 5;
    const ll mod = 2017;
    const ll INF = 0x3f3f3f3f;
    const ll INF64 = 0x3f3f3f3f3f3f3f3f;
    const double gold = (1 + sqrt(5)) / 2.0;
    const double PI = acos(-1);
    const double eps = 1e-8;
    ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
    ll pow(ll x, ll y, ll mod) { ll ans = 1; while (y) { if (y & 1)ans = (ans * x) % mod; x = (x * x) % mod; y >>= 1; }return ans; }
    ll pow(ll x, ll y) { ll ans = 1; while (y) { if (y & 1)ans = (ans * x) % mod; x = (x * x) % mod; y >>= 1; }return ans; }
    ll inv(ll x) { return pow(x, mod - 2); }
    
    priority_queue<int,vector<int> ,greater<int> >pq;
    char com[100005][10];
    int s[100005];
    string p;
    int main() {
    	int n,m;
    	
    	scanf("%d", &n);
    	m = n;
    	for (int i = 0; i < n; i++) {
    		scanf("%s", com[i]);
    		if (com[i][0] != 'r')
    			scanf("%d", &s[i]);
    	}
    
    	for (int i = 0; i < n; i++) {
    		if (com[i][0] == 'i') {
    			pq.push(s[i]);
    		}
    		else if (com[i][0] == 'r') {
    			if (pq.empty()) {
    				p += "insert 0\n";
    				m++;
    			}
    			else {
    				pq.pop();
    			}
    
    		}
    		else {
    
    			while (pq.size() && pq.top() < s[i]) {
    				p+="removeMin\n";
    				m++;
    				pq.pop();
    			}
    			if (pq.empty() || pq.top() != s[i]) {
    				p+="insert "+to_string(s[i])+'\n';
    				m++;
    				pq.push(s[i]);
    			}
    		}
    		p += com[i];
    		p+=' ';
    		if (com[i][0] != 'r')p += to_string(s[i]);
    		p += '\n';
    
    	}
    	
    	cout<< m <<'\n'<< p;
    	return 0;
    }
    

    B Game with string CodeForces - 1104B

    题意

    题意:
    两个人正在围绕着一个仅有小写字母组成的字符串 s玩一个游戏
    在一个玩家的回合, 他必须选择字符串中的两个相邻并且相同字母删除。
    例如, 如果当前字符串是 “xaax” 那么就只有一种可能,删除 “aa”, 所以字符串将变为 “xx”。两个人都想赢。
    现在需要你求出最后谁会赢如果两人都选择最优策略。

    题解

    容易知道删除字符的顺序不影响总删除次数,所以实际上对于一个特定的字符串,删除次数是固定不变的,因此我们只要求出总次数然后判断奇偶性就好,判断使用栈判断,其他方法也行,栈比较方便。

    AC代码

    char s[100005];
    char st[100005];
    int main(){
    	int n,k=0,ans=0;
    	scanf("%s",s);
    	for(int i=0;s[i];i++){
    		if(k==0){
    			st[k++]=s[i];
    		}
    		else{
    			if(st[k-1]==s[i]){
    				k--;
    				ans++;
    			}
    			else {
    				st[k++]=s[i];
    			}
    		}
    
    	}
    	printf("%s\n",ans%2?"Yes":"No");
    
    	return 0;
    }
    

    C Splitting into digits CodeForces - 1104A

    题意

    将给定数拆分成多个数的组合,使种类尽量少。

    题解

    数据很小全部拆成1就好

    AC代码

    int main(){
        int n;
        scanf("%d",&n);
        printf("%d\n",n);
        for(int i = 0; i < n; i++){
            printf("1 ");
        }
        printf("\n");
        return 0;
    }
    

    D Sudoku POJ - 2676

    题意

    九宫格问题,也叫数独问题。把一个9行9列的网格,再细分为9个3*3的子网格,要求每行、每列、每个子网格内都只能使用一次1~9中的一个数字,即每行、每列、每个子网格内都不允许出现相同的数字。0是待填位置,其他均为已填入的数字。要求填完九宫格并输出(如果有多种结果,则只需输出其中一种)。如果给定的九宫格无法按要求填出来,则输出原来所输入的未填的九宫格。

    题解

    经典dfs问题,直接搜索容易超时,要一定程度的优化,使用bh[i][x]判断第i行的x有无出现过;使用bl[i][x]判断第i列的x有无出现过;使用bk[i][x]判断第i块的x有无出现过。

    AC代码

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n = 0;
    int f[11][11];
    int bh[11][11], bl[11][11], bk[11][11];
    int flag;
    struct point {
    	int x, y;
    };
    point l[82];
    
    int judge(int x, int y) {
    	for (int i = 1; i <= 3; i++)
    		for (int j = 1; j <= 3; j++)
    			if (x <= 3 * i&&y <= 3 * j)
    				return (i - 1) * 3 + j;
    
    }
    
    void dfs(int num) {
    	if (flag)return;
    	if (num == n) {
    		printf("\n");
    		for (int i = 1; i <= 9; i++) {
    			for (int j = 1; j <= 9; j++)
    				printf("%d", f[i][j]);
    			printf("\n");
    		}
    		flag = 1;
    		return;
    	}
    	int x = l[num].x, y = l[num].y;
    	int k = judge(l[num].x, l[num].y);
    	for (int i = 1; i <= 9; i++) {
    		if (!bh[x][i] && !bl[y][i])
    			if (!bk[k][i]) {
    				bh[x][i] = bl[y][i] = bk[k][i] = 1;
    				f[x][y] = i;
    
    				dfs(num + 1);
    
    				bh[x][i] = bl[y][i] = bk[k][i] = 0;
    				f[x][y] = 0;
    			}
    	}
    
    }
    
    
    
    int main() {
    	int t;
    	cin >> t;
    	while (t--) {
    		flag = 0;
    		n = 0;
    		for (int i = 1; i <= 9; i++)
    			for (int j = 1; j <= 9; j++) {
    				scanf("%1d", &f[i][j]);
    				if (f[i][j] == 0)l[n++] = { i,j };
    				else {
    					bh[i][f[i][j]] = 1;
    					bl[j][f[i][j]] = 1;
    					bk[judge(i, j)][f[i][j]] = 1;
    				}
    			}
    		dfs(0);
    		for (int i = 0; i < 11; i++)
    			for (int j = 0; j < 11; j++) {
    				f[i][j] = 0;
    				bl[i][j] = 0;
    				bh[i][j] = 0;
    				bk[i][j] = 0;
    			}
    		for (int i = 0; i < 82; i++) {
    			l[i].x = 0;
    			l[i].y = 0;
    		}
    	}
    	return 0;
    }
    
    

    E 均分纸牌 计蒜客 - T2158

    题意

    均分纸牌

    题解

    经典贪心问题,求出平均数也就是最终状态,然后递推一遍算次数就好。

    AC代码

    int s[102];
    int main() {
    	int n,sum=0,ans=0;
    	scanf("%d", &n);
    	for (int i = 0; i < n; i++) {
    		scanf("%d", s + i);
    		sum += s[i];
    	}
    	sum /= n;
    	
    	for (int i = 0; i < n; i++) {
    		if(i)s[i] += s[i - 1] - sum;
    		ans += (s[i] - sum) ? 1 : 0;
    	}
    	printf("%d\n", ans);
    	return 0;
    }
    

    F Space Navigation CodeForces - 1481A

    题意

    从给定的操作中选择一些,问你能否达到终点。

    题解

    统计下各种操作个数,然后比较下大小就好。

    AC代码

    char s[N];
     
    int main() {
    	int t,px,py;
    	scanf("%d", &t);
    	while (t--) {
    		int u, d, l, r;
    		u = d = l = r = 0;
    		scanf("%d%d%s", &px, &py, s);
    		for (int i = 0; s[i]; i++) {
    			if (s[i] == 'U')u++;
    			else if (s[i] == 'D')d++;
    			else if (s[i] == 'L')l++;
    			else if (s[i] == 'R')r++;
    		}
    		if (py <= u && py >= -d && px <= r && px >= -l)
    			printf("YES\n");
    		else printf("NO\n");
     
     
    	}
    	
    	
    	
    	return 0;
    }
    

    G Mishka and Contest CodeForces - 999A

    题意

    给出 n 个问题的难度以及可以解决问题的能力 k,每次只能从问题列表的左边或右边解决问题,如果问题难度高于 k,其后或其前的问题就无法解决,求最多可以解决多少问题。

    题解

    分别从右向左、从左向右枚举,注意如果 k 大于所有问题的难度,即解决的问题数为2倍的给出问题数,直接输出问题数即可。

    AC代码

    nt s[105];
    int main() {
    	int n, k;
    	scanf("%d%d",&n,&k);
    	for (int i = 0; i < n; i++)
    		scanf("%d", s + i);
    	int ans = 0;
    	for (int i = 0; i < n; i++) {
    		if (s[i] > k) {
    			break;
    		}
    		ans++;
    	}
    	for (int i = n-1; i>=0; i--) {
    		if (s[i] > k) {
    			break;
    		}
    		ans++;
    	}
    	if (ans > n)ans /= 2;
    	printf("%d\n", ans);
    	return 0;
    }
    
  • 相关阅读:
    一个群发站内信的设计
    javascript typeof 小结
    setInterval,setTimeout的用法
    C#中常见异常类
    输入框关闭自动完成功能
    【转】javascript判断一个元素是否数组
    jquery的动态统计输入字符数方法
    giedview绑定数据格式化字符串
    jQuery 1.4单独为某个动画动作设效果
    GridView行编辑中找DropDownList控件
  • 原文地址:https://www.cnblogs.com/komet/p/15872002.html
Copyright © 2020-2023  润新知