A. Three Pairwise Maximums #构造

题目链接

题意

给定三个正整数\(x,y,z\),要求找出正整数\(a,b,c\),满足\(x=max(a,b), y=max(a,c),z=max(b,c)\)

分析

我们可以先将\(x,y,z\)降序排序得到\(z\leq y\leq x\)。由于\(x\)是\(a,b,c\)三者最值,且通过三个关系中\(x\)所代表的数字一定出现两次,可以推断出,\(y=x\),如果最值没有出现两次,说明我们不可能构造出\(a,b,c\)。

既然题目让我们构造,构造且要满足\(max(a,b)=max(a,c)\),那么不妨设\(a\)为最大值,即\(a=x=y\)。由于\(z\)能推出\(b,c\)关系,我们又不妨将\(b\)赋为\(z\)(三值中第二大)。三者最小值不易准确确定,直接将\(c\)赋值为1,作为三者中的最小值,十分稳妥。

#include <algorithm>
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 5;
const int MOD = 1e4 + 7;
int n, m, q;
int main(){
scanf("%d", &q);
while(q--){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
if(x<y) swap(x,y);
if(x<z) swap(x,z);
if(y<z) swap(y,z); //排序一下
if(x != y) {
printf("NO\n");
continue;
}
else{
printf("YES\n");
printf("%d %d %d\n", x, z, 1);
}
}
return 0;
}

C. Make It Good #贪心

题目链接

题意

“好数组”定义为,一个数组\(b\),我们只从该数组最左边,或者最右边,将所有元素依次取出并放到\(c\)数组,该\(c\)数组是个不降序列,则称\(b\)数组为“好数组”。

现给定数组\(a\),你需要从数组\(a\)的前几个元素删去,得到一个“好数组”。现要你求出删除的前几个元素至少需要多少。比如数组a={4 3 3 8 4 5 2},你至少需要删除前面4个元素,得到的数组b={4 5 2}才是个好数组。

分析

不难分析,“好数组”中的元素关系必然是\(b_1 \leq b2 \leq ... \leq\) \(b_{mi}\) \(\geq ... \geq b_k\),其中\(b_{mi}\)为数组\(b\)中最大值(不一定是数组\(a\)中最大值),简单来说,我们就是要从\(a\)数组中找到“山峰”。

由于我们只能删除数组\(a\)中前面几个元素,因而后面元素受到的影响很少,于是我们用一右指针\(hi\),从数组\(a\)的后面往前面遍历,只要\(a[hi-1]\geq a[hi]\)就往前进(相当于走上坡),一旦遇到\(a[hi-1] \leq a[hi]\)说明到达极值点。我们再继续往前面(往数组左端)遍历,只要\(a[hi-1]\leq a[hi]\)就往前进(相当于走下坡),一旦遇到\(a[hi-1] \geq a[hi]\)说明到达我们到达山底,即\(a[1, ...hi-1]\)的元素都需要删去,\(a[hi, n]\)方为好数组。敲代码时注意下边界。

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 5;
int n, m, q;
int a[MAXN];
int main(){
scanf("%d", &q);
while(q--){
scanf("%d", &n);
for(int i =1 ; i <= n; i++) scanf("%d", &a[i]);
int hi = n;
while(hi >= 1 && a[hi-1] >= a[hi]) hi--; //走上坡
while(hi >= 1 && a[hi - 1] <= a[hi]) hi--; //走下坡
if(hi - 1 >= 0) printf("%d\n", hi - 1);
else printf("0\n");
}
return 0;
}

D. a-Good String #暴力深搜 #分治

题目链接

题意

“\(a\)-好串”定义为,不小于一个元素的串,满足以下其中一个条件即可:

  • 若长度为1,且包含的字符恰好为\(a\)。
  • 若长度大于1,且它的左半部分所有字符均为\(a\),而另一半的串是“\(a+1\)-好串”(\(a+1\)字符,即为字符a在字母表中下一个字符)
  • 若长度大于1,且它的右半部分所有字符均为\(a\),而另一半的串是“\(a+1\)-好串”

\(t(\leq2\times 10^{5})\)组询问,给定长度为\(n(其中\sum n \leq 2\times 10^{5})\)串,你可以对串中任意字符转变为其他任意字符,每个字符的转变作为一次操作,现要你求出将串转变为“\(a-\)好串”的最少次数

分析

先将串中所有种字符进行前缀和统计,然后对于串的前后部分暴力搜索一下即可,因为递归下来,大约有\(logn\)种子串,层数大约为十多层,\(O(nlogn)\)复杂度能够通过\(t\)组询问。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
using namespace std;
typedef long long ll;
const int MAXN = 150000;
int q, n, sum[30][MAXN];
string str;
int dfs(int lo, int hi, int cur){
int mid = (lo + hi) >> 1, len = hi - lo + 1;
if(len <= 1) //边界情况
return len - sum[cur][hi] + sum[cur][hi - 1];
int pre = (len >> 1) - sum[cur][mid] + sum[cur][lo - 1];
int lat = (len >> 1) - sum[cur][hi] + sum[cur][mid];
int res = min(dfs(lo, mid, cur+1) + lat, dfs(mid+1, hi, cur+1) + pre);
return res;
}
void preCal(){
for (int i = 1; i <= 26; i++){
for (int j = 0; j < str.length(); j++){
sum[i][j + 1] = sum[i][j];
if(str[j] - 'a' + 1 == i)
sum[i][j + 1]++;
}
}
}
int main(){
scanf("%d", &q);
while(q--){
scanf("%d", &n); cin >> str;
preCal();
printf("%d\n", dfs(1, n, 1));
}
}

E. Directing Edges #拓扑排序

题目链接

题意

给定一个图,里面既包含有向边,也包含无向边,并保证初始情况下的图不存在平行边与自环,现要你将图中所有无向边改变为有向边(方向自定义),使得图不存在任何一个有向环。如果无法保证不出现有向环,输出"NO"。否则需要你输出所有边的连接信息。

分析

容易知道,初始情况下的无向边并不会影响图是否存在有向环,应关注于当前的所有有向边所组成的图。如何判断是否存在有向环,利用拓扑排序算法即可,但别忘了要将拓扑序列存下来,这是用于判断无向边指向的方向。如果一条无向边中的顶点\(a\)的拓扑序小于顶点\(b\),那么\(a\)应该指向\(b\),反之,让\(b\)指向\(a\)。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
const int MAXN = 2e5+5;
int q, n, m;
struct Edge{ //用于输出
int u, v;
} E[MAXN << 1];
struct BuildEdge{ //用于拓扑排序
int to, nextNbr;
} BE[MAXN << 1];
int H[MAXN], tot = 0, InD[MAXN], num = 0;
int ans[MAXN];
void addEdge(int u, int v){
tot++;
BE[tot] = {v, H[u]};
H[u] = tot;
}
bool ToSort(){
queue<int> myque;
int res = 0;
for(int i = 1; i <= n; i++){
if(InD[i] == 0){
myque.push(i);
ans[i] = ++res; //记录拓扑序
}
}
while(!myque.empty()){
int cur = myque.front();
myque.pop();
for(int i = H[cur]; i >= 0; i = BE[i].nextNbr){
int v = BE[i].to; InD[v]--;
if(InD[v] == 0){
myque.push(v);
ans[v] = ++res; //记录拓扑序
}
}
}
return (res != n); //如果不相等,说明存在有向环
}
void Init(){ //初始化
memset(H, -1, sizeof(H));
memset(ans, 0, sizeof(ans));
memset(InD, 0, sizeof(InD));
tot = num = 0;
for (int i = 1; i <= m; i++) BE[i] = {-1, -1};
}
int main(){
scanf("%d", &q);
while(q--){
scanf("%d%d", &n, &m);
Init();
for (int i = 1, u, v, opt; i <= m; i++){
scanf("%d%d%d", &opt, &u, &v);
E[++num] = {u, v};
if(opt == 1){ //有向边建图
addEdge(u, v);
InD[v]++;
}
}
bool isLoop = ToSort();
if(isLoop) printf("NO\n");
else{
printf("YES\n");
for(int i = 1; i <= m; i++){
int u = E[i].u, v = E[i].v;
if(ans[u] < ans[v]) printf("%d %d\n", u, v);
else printf("%d %d\n", v, u);
}
}
}
return 0;
}

Codeforces Round #656 (Div. 3) 题解的更多相关文章

  1. Codeforces Round #182 (Div. 1)题解【ABCD】

    Codeforces Round #182 (Div. 1)题解 A题:Yaroslav and Sequence1 题意: 给你\(2*n+1\)个元素,你每次可以进行无数种操作,每次操作必须选择其 ...

  2. Codeforces Round #608 (Div. 2) 题解

    目录 Codeforces Round #608 (Div. 2) 题解 前言 A. Suits 题意 做法 程序 B. Blocks 题意 做法 程序 C. Shawarma Tent 题意 做法 ...

  3. Codeforces Round #525 (Div. 2)题解

    Codeforces Round #525 (Div. 2)题解 题解 CF1088A [Ehab and another construction problem] 依据题意枚举即可 # inclu ...

  4. Codeforces Round #528 (Div. 2)题解

    Codeforces Round #528 (Div. 2)题解 A. Right-Left Cipher 很明显这道题按题意逆序解码即可 Code: # include <bits/stdc+ ...

  5. Codeforces Round #466 (Div. 2) 题解940A 940B 940C 940D 940E 940F

    Codeforces Round #466 (Div. 2) 题解 A.Points on the line 题目大意: 给你一个数列,定义数列的权值为最大值减去最小值,问最少删除几个数,使得数列的权 ...

  6. Codeforces Round #677 (Div. 3) 题解

    Codeforces Round #677 (Div. 3) 题解 A. Boring Apartments 题目 题解 简单签到题,直接数,小于这个数的\(+10\). 代码 #include &l ...

  7. Codeforces Round #665 (Div. 2) 题解

    Codeforces Round #665 (Div. 2) 题解 写得有点晚了,估计都官方题解看完切掉了,没人看我的了qaq. 目录 Codeforces Round #665 (Div. 2) 题 ...

  8. Codeforces Round #160 (Div. 1) 题解【ABCD】

    Codeforces Round #160 (Div. 1) A - Maxim and Discounts 题意 给你n个折扣,m个物品,每个折扣都可以使用无限次,每次你使用第i个折扣的时候,你必须 ...

  9. Codeforces Round #383 (Div. 2) 题解【ABCDE】

    Codeforces Round #383 (Div. 2) A. Arpa's hard exam and Mehrdad's naive cheat 题意 求1378^n mod 10 题解 直接 ...

随机推荐

  1. LoRaWAN和LoRa的区别在那里?

    有很多人都分不清楚LoRaWAN和LoRa到底有什么区别,甚至有人认为它们是一样的,但其实这两个不一样的. LoRa是一个物理层的协议,而LoRaWAN则指的是MAC层的组网协议.虽然现有的LoRaW ...

  2. C# Base64解码小工具编写

    1 界面如下 2 关键代码如下 try { var callback = reqStr.Deserialize<dynamic>(); resStr = Newtonsoft.Json.J ...

  3. JDK 8 新增的 LongAdder,得过来看一下

    前言 在介绍 AtomicInteger 时,已经说明在高并发下大量线程去竞争更新同一个原子变量时,因为只有一个线程能够更新成功,其他的线程在竞争失败后,只能一直循环,不断的进行 CAS 尝试,从而浪 ...

  4. Ideas and Tricks Part II

    33.对于统计答案幂次的技巧 对于$x^k$,考虑其组合意义:将$k$个不同球放到$x$个不同的盒子里的方案数,直接维护不好维护,那么考虑枚举把这些球放到了哪些盒子里,最后乘上第二类斯特林数和对于的阶 ...

  5. 跟我一起学.NetCore之EF Core 实战入门,一看就会

    前言 还记得当初学习数据库操作时,用ADO.NET一步一步地进行数据操作及查询,对于查询到的数据还得对其进行解析,然后封装返回给应用层:遇到这种重复而繁琐的工作,总有一些大神或团队对其进行封装,从而出 ...

  6. c# 创建delphi的代码

    需求: 有一个专业表,没有插入数据,读取的excel,复制为txt文件 每行读取 并且 将汉字的一转换为数字1 private void barButtonItem4_ItemClick(object ...

  7. ubuntu12.04管理文件系统工具

    ubuntu12.04管理文件系统工具 以前可以自动管理系统盘和移动硬盘,刚重新安装了UBUNTU12.04LTS之后不行了,原来是这个工具: "PCMANFM" 群星_-_偏偏喜 ...

  8. 索引--mysql 数据库Load data大量数据时性能因素之一

    发现load data infile 插入数据时越来越慢,后来发现是因为创建表时有创建索引的动作. 把索引创建删除掉之后,导入很迅速,导入后再创建索引,效率果有提高.

  9. 解决 Vmware 服务拒绝访问的问题

    背景 在服务页面想将 VMware NAT Service 设置为自动开启的,但是保存的时候显示拒绝访问,如下图 解决方案 想到在本机的火绒启动项管理里面将 VMware NAT Service 设置 ...

  10. @AliasFor注解

    @AliasFor注解 @AliasFor是一个注解,用于为注解属性声明别名. 代码如下:它有两个属性value和attribute @AliasFor注解注释了 自身,并且value和attribu ...