Codeforces Round #423 (Div. 2)A B C D

A. Restaurant Tables

题意是一个点单人座有a个双人座有b个,有n组人,每组人有一个或两个人。当一个人时优先坐单人座的没有就坐没有人坐的双人座,然后才是在已经坐了一人的双人座,还没有就拒绝为他服务。当两个人时,只坐双人座的没有就拒绝服务。问这个店要拒绝服务多少人。

直接模拟下就行了。

 1 #include <iostream>
 2 #include <string.h>
 3 #include <stdio.h>
 4 using namespace std;
 5
 6 int main(){
 7     int n,a,b,flag = 0,num,ans= 0;
 8     cin>>n>>a>>b;
 9     for(int i = 1; i <= n; i ++){
10         cin>>num;
11         if(num==1){
12             if(a>0)a--;
13             else if(a==0){
14                 if(b>0)b--,flag++;
15                 else if(b==0&&flag>0)flag--;
16                 else if(b==0&&flag==0)ans++;
17             }
18         }else if(num==2){
19             if(b>0)b--;
20             else if(b==0)ans+=2;
21         }
22     }
23     cout << ans << endl;
24     return 0;
25 }

B. Black Square

题意是有n行m列,让W变成B,使的所以的B组成一个正方形,求最小的改变数,没有就输出-1,一开始我以为B会有两个以上的区域,看了别人的代码才发现不是这么一回事,

B所在的区域最多只有一个区域,这样求下出先B的最大i,最小i,最大j,最小j,max((di-mi),(dj-mj))就是最小的正方形边长了,只要边长小于n或者m就是-1,这样就求出答案了。

还是要多刷题多思路,加油!

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 using namespace std;
 5 int n,m,di,dj,mi=1e9,mj=1e9;
 6 char str[110][110];
 7
 8 int main(){
 9     scanf("%d %d",&n,&m);
10     for(int i = 0; i < n; i ++)cin>>str[i];
11     int ans = 0;
12     for(int i = 0; i < n; i ++){
13         for(int j = 0; j < m; j ++){
14             if(str[i][j]==‘B‘){
15                 ans++;
16                 di=max(di,i),mi=min(mi,i);
17                 dj=max(dj,j),mj=min(mj,j);
18             }
19         }
20     }
21     if(!ans){
22         puts("1");
23         return 0;
24     }
25
26     int k = max((di-mi),(dj-mj))+1;
27     printf("%d\n",k>n||k>m?-1:k*k-ans);
28     return 0;
29 }

C. String Reconstruction

题意:有n个字符串,每个字符串出现了k次,每次出现的位置时是ki,求完整的字符串,要求字典最小。一开始直接暴力了,时间超限了。

后来想想,n个字符串可以让他们分别标记为1,2,3...n,这样每输入i字符串的k次位置时,可以用数组保存下。

当然,有些字符串出现的位置可以相同,这样可以让数组储存长度最大的那个字符串。

输出时,可以定义一个变量p,它的作用代表已经输出了p个字符。当然,之前输入位置时要先计算下可以输出的最大字符串记为Max,

然后定义一个i用来扫描数组,

(一)当a[i]=0,且i>p时说明当前已经输出了p个字符,现在要输出第i个字符,由于a[i]没有被标记就直接输出字符a,因为是求字典最小的,所以就直接输出a了。

(二)当a[i]=0,且i<=p时,说明第i个位置没有被标记,又因为i<=p,就直接扫描下一个位置了。

(三)这个就是最重要的了。到这步就说明第i个位置已经被标记了,先取出它的值(代表了第几个字符串),然后在算下长度len,

      ①当i+len-1<=p时(-1是因为要输出len个字符的话是从i开始的)说明第i个位置代表的字符串已经被输出了,比如前面输出了abcde,现在要从第3个位置输出cd,由于之前输出了,就直接扫描下一个位置就行了,

      ②当i+len-1>p时,就输出a[i]代表的字符串从第p-i+1开始输出就行,比如前面输出了abcdef,现在要从第4个位置输出defgh,由于前面输出了def,所以现在直接输出gh就行了。

所以用线性的时间就可以做出来了,一时头脑发热就想出来了,加油!

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <vector>
 5 using namespace std;
 6 const int MAX = 2e6+10;
 7 int a[MAX];
 8 vector<string> vs;
 9 int main(){
10     int n,Max = 0,k,num;
11     scanf("%d",&n);
12     for(int i = 1; i <= n; i ++){
13         string s;
14         cin >> s;
15         vs.push_back(s);
16         scanf("%d",&k);
17         for(int j = 1; j <= k; j ++){
18             scanf("%d",&num);
19             if(a[num]==0){
20                 a[num]=i;
21             }else if(vs[a[num]-1].length() < s.length()){
22                 a[num] = i;
23             }
24             if(num+s.length()-1 > Max){
25                 Max = num+s.length()-1;
26             }
27         }
28     }
29     int i = 1,p=0;
30     while(i <= Max){
31         if(a[i]==0&& i>p){
32             printf("a");
33             i++;p++;
34         }else if(a[i]==0&&i<=p){
35             i++;
36         }else{
37             int ans = a[i];
38             int len = vs[ans-1].length();
39
40             if(i+len-1<=p){
41                 i++;continue;
42             }else if(i+len-1>p){
43                 string ss = vs[ans-1].substr(p-i+1,len);
44                 cout << ss;
45                 p = i+len-1;
46                 i++;
47             }
48         }
49     }
50     return 0;
51 }

D. High Load

题意是有n个节点,其中有k个输出节点,输出节点要连接输出网络,所以可以把它看出只连接一个节点的节点,其它节点只要要连接两个节点,要求出输出节点最远的两个的最小距离,并输出所有节点的连接情况。

想好好久也想不出,看了大牛的才发现这题是多么的简单,可以把一个节点当成最中心节点,然后在它上连接K个节点就行,一直连下去。

下图是 n=7,k=3的情况,看了这图就应该可以秒做这到题目了。

直接贴代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 using namespace std;
 4
 5 int main(){
 6     int n,k;
 7     cin>>n>>k;
 8     int h = (n-1)/k;
 9     if((n-1)%k==0) printf("%d\n",2*h);
10     else if((n-1)%k==1)printf("%d\n",2*h+1);
11     else printf("%d\n",2*h+2);
12     for(int i = 2; i <= k+1; i ++)printf("1 %d\n",i);
13     for(int i = k+2; i <= n; i ++)printf("%d %d\n",i-k,i);
14     return 0;
15 }
时间: 2024-08-27 11:25:27

Codeforces Round #423 (Div. 2)A B C D的相关文章

Codeforces Round #615(Div.3)解题报告

Codeforces Round #615(Div.3)解题报告 A. Collecting Coins 注意\(n\)可能不够用的情况. #include<bits/stdc++.h> using namespace std; typedef long long ll; int a, b, c, n; void solve() { cin >> a >> b >> c >> n; int mx = max(max(a, b), c); int

Codeforces Round #626 (Div. 2) B. Count Subrectangles

题目连接:https://codeforces.com/contest/1323/problem/B 题意:给一个大小为n的a数组,一个大小为m的b数组,c数组是二维数组c[i][j]=a[i]*b[j],问面积为k的矩形有几个. 题解:先把k的所有因子存入一个数组里,然后遍历因子,表示在a数组有 i 个连续的1,那么如果在b数组里有 k/i 个连续的1,形成的矩形面积就是k(自己脑补一下吧),计算出a数组中符合条件的个数乘以b数组中符合条件的个数,然后把每个因子下的都加起来就是答案. 1 #i

Educational Codeforces Round 63-D(基础DP)

题目链接:https://codeforces.com/contest/1155/problem/D 题意:给定n个数,可以选择一段连续子段将其乘x,也可以不操作,求最大连续子段和. 思路:比赛时觉得是dp,但怎么也想不出来QAQ,dp太难了...赛后看了别人题解,找到状态和转移方程就很简单了,然而比赛时我就是想不到... 考虑下标i:有3种情况,可能[0,i]都没有乘x,可能i乘了x,可能[i,n]都不会乘x.分别用dp[i][0]表示以i结尾的最长子段和且 [0,i]都没乘x,dp[i][1

Codeforces Round #423 (Div. 2) C 思维,并查集 或 线段树 D 树构造,水

Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) C. String Reconstruction   思维,并查集 或 线段树 题意:一个字符串被删除了,但给出 n条信息,要还原出可能的字典序最小的字符串.信息有:字符串ti,ki个位置xi,表明原本的字符串在xi位置是以字符串ti开头的. tags:惨遭 fst,一开始把所有字符串都存下来,排序做的,结果爆内存了.. 方法1: 考虑并查集,对于字符串 ti,在位置xi,

Codeforces Round #423 (Div. 2) D. High Load(构造题)

题目链接:Codeforces Round #423 (Div. 2) D. High Load 题意: 给你一个数n和k,让你构造出一颗树,有k个叶子节点,使得这棵树的任意两个点的距离的最大值最小. 题解: 显然要使得这棵树的任意两个点的距离的最大值最小,每个点离树根越近越好. 然后要求有k个叶子节点,所以我就任意选一个点为根,然后构成一棵m叉的树就行了. 最大距离的最小值就是离根最远的和最近的加一加就行了. 1 #include<cstdio> 2 #define F(i,a,b) for

Codeforces Round #FF(255) (Div. 2)

A题 /* ID: neverchanje PROG: LANG: C++11 */ #include<vector> #include<iostream> #include<cstring> #include<string> #include<algorithm> #include<cmath> #include<cstdio> #include<set> #include<queue> #inc

Codeforces Round #277.5 (Div. 2) JAVA版题解

Codeforces Round #277.5 (Div. 2) A. SwapSort time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output In this problem your goal is to sort an array consisting of n integers in at most n swaps. For t

Codeforces Round #277.5 (Div. 2) b

/**  * @brief Codeforces Round #277.5 (Div. 2) b  * @file b.c  * @author 面码  * @created 2014/11/18 17:22  * @edited  2014/11/18 17:22  * @type greedy  *  */ #include <stdio.h> #define MAXN 110 #define max(a, b)  ((a) > (b) ? (a) : (b)) #define mi

Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) A. Single Wildcard Pattern Matching B. Pair of Toys C. Bracket Subsequence D. Array Restoration-区间查询最值(RMQ(ST))

Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) A. Single Wildcard Pattern Matching 题意就是匹配字符的题目,打比赛的时候没有看到只有一个" * ",然后就写挫了,被hack了,被hack的点就是判一下只有一个" * ". 1 //A 2 #include<iostream> 3 #include<cstdio&g