Educational Codeforces Round 54 ---1076ABCDE
1076A---Minimizing the String【字符串】
http://codeforces.com/contest/1076/problem/A
题意:
删掉字符串中的一个字符使得得到的字符串是字典序最小的一种。
思路:
从头到尾找到第一个字符他比他后面的一个字典序要大,那就是要删掉的。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define ll long long
#define N 100010
#define pi 3.1415926535 int n;
const int maxn = 2e5 + ;
char str[maxn], ans[maxn]; int main()
{
while(scanf("%d", &n) != EOF){
memset(ans, , sizeof(ans));
memset(str, , sizeof(str));
scanf("%s", str);
int len = ;
bool flag = true;
for(int i = ; i < n - ; i++){
if(str[i] > str[i + ] && flag){
flag = false;
continue;
}
ans[len++] = str[i];
}
if(!flag){
ans[len++] = str[n - ];
} printf("%s\n", ans);
}
return ;
}
1076B---Divisor Subtraction【数论】【思维】
http://codeforces.com/contest/1076/problem/B
题意:
给定一个数n,每次让他减掉他的最小质因子。问总共要减去多少次。
思路:
这题卡了好久....刚开始想着存一下质因子?但是存不下的啊。然后也想不到怎么优化时间。
对于n,如果他是偶数,那么他一定有质因子2。并且他减去2之后还是偶数,还是有质因子2.所以他的答案就是\(n/2\)
如果n是奇数,那么他减去了一个不是2的质因子之后就会变成偶数,就还是上面的步骤。那么现在就要找n的最小质因子。
找最小质因子其实根本不用去判断他是不是质数。这一点没想到有点傻了。
因为最小的因子肯定是质数否则肯定有一个比他还小的因子。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
typedef long long LL;
#define N 100010
#define pi 3.1415926535 LL n; bool isprime(LL x)
{
for(LL i = ; i <= sqrt(x); i++){
if(x % i == )return false;
}
return true;
} LL getPri(LL x)
{
LL ans = -;
for(LL j = ; j * j <= x; j++){
if(x % j == ){
if(ans == -)return j;
while(x % j == )x /= j;
}
}
if(x > ){
if(ans == -)return x;
}
return ans;
} int main()
{
while(scanf("%lld", &n) != EOF){
LL num = ;
if(n % == ){
num = n / ;
}
else{
for(LL j = ; j * j <= n; j++){
if(n % j == ){
n -= j;
num++;
break;
}
}
if(num == ){
n = ;
num++;
}
num += n / ;
} printf("%lld\n", num);
}
return ;
}
1076C---Meme Problem【公式】
http://codeforces.com/contest/1076/problem/C
题意:
给一个正整数d,要求你找出两个正数a和b,使得\(a+b=d,a*b=d\)
思路:
傻子我居然第一反应是二分。
直接代进去解方程就可以了。
\(x_{1,2} = \frac{d \pm \sqrt{d^{2}-4d}}{2}\),\(d^{2} - 4d < 0\)时不存在
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
typedef long long LL;
#define N 100010
#define pi 3.1415926535 int t;
double d;
const double eps = 1e-; int main()
{
scanf("%d", &t);
while(t--){
scanf("%lf", &d);
double delta = d * d - * d;
if(delta < ){
printf("N\n");
}
else{
delta = sqrt(delta);
double a = (d - delta) / , b = (d + delta) / ;
printf("Y %.9f %.9f\n", max(a,b), min(a,b));
} }
return ;
}
1076D---Edge Deletion【最短路】【贪心】
http://codeforces.com/contest/1076/problem/D
题意:
给定一个n个节点m条边的图。现在要把边删到只有k条。删除边时要使尽可能多的节点i,节点1到节点i的最短路在删边前和删边后保持不变。
思路:
首先肯定要先跑dijstra找到单源最短路。
那么我们要删掉哪些边呢。这条边肯定尽可能少的出现在最短路的路径中。
由于dijkstra是用一种贪心的策略,他每次选的都是未拓展的且d最小的一个节点进行拓展。
如果\(d[j] > d[i]\),那么\(1~j\)的路中只要有\(i\)最短路就会经过\(i\)
所以得到最短路之后,可以按照d的大小排序,保留小的删除大的。
为了知道哪些边是留着的我们需要保存一下松弛时是由那条边拓展来的。
因为存的是双向边,所以最后输出的时候还需要处理一下。
注意d和队列都要开longlong
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
typedef long long LL;
#define N 100010
#define pi 3.1415926535 const int maxn = 3e5 + ;
int n, m, k;
int head[maxn];
LL d[maxn];
bool vis[maxn];
struct edge{
int v, nxt;
LL w;
}e[maxn * ];
int tot, pre[maxn]; void addedge(int x, int y, LL z)
{
e[tot].v = y;
e[tot].w = z;
e[tot].nxt = head[x];
head[x] = tot++;
e[tot].v = x;
e[tot].w = z;
e[tot].nxt = head[y];
head[y] = tot++;
} void dijkstra()
{
priority_queue<pair<LL, int> > que;
memset(d, 0x3f, sizeof(d));
memset(vis, , sizeof(vis)); d[] = ;
que.push(make_pair(, ));
while(que.size()){
int x = que.top().second;que.pop();
if(vis[x])continue;
vis[x] = true;
for(int i = head[x]; i != -; i = e[i].nxt){
int y = e[i].v, z = e[i].w;
if(d[y] > d[x] + z){
d[y] = d[x] + z;
que.push(make_pair(-d[y], y));
pre[y] = i;
}
}
}
} int main()
{
while(scanf("%d%d%d", &n, &m, &k) != EOF){
tot = ;
memset(head, -, sizeof(head));
for(int i = ; i < m; i++){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
addedge(x, y, 1LL * z);
}
dijkstra(); vector<pair<LL, int>>vec;
for(int i = ; i <= n; i++){
//printf("%d\n", pre[i]);
vec.push_back(make_pair(d[i], pre[i]));
}
sort(vec.begin(), vec.end());
vector<int>ans;
for(int i = ; i < vec.size(); i++){
if(i == k)break;
ans.push_back(vec[i].second);
}
cout<<ans.size()<<endl;
for(int i = ; i < ans.size(); i++){
if(ans[i] % == ){
printf("%d ", ans[i] / + );
}
else{
printf("%d ", (ans[i] ^ ) / + );
}
}
printf("\n");
}
return ;
}
1076E---Vasya and a Tree【dfs】
http://codeforces.com/contest/1076/problem/E
题意:
给定给一个以1位根的树,现在给m次操作。每次操作给定v,d,x,表示更新以v为根的子树中距离v的距离是d之内的所有节点,将这些节点的值加上x。现在求更新完成之后各个节点的值。
思路:
我们将所有的更新操作统一进行。每次dfs下去进行更新。
沿着树的一条路径走,节点v的那些父节点的更新都会对v的值产生影响。我们就用一个数组add来记录这些影响。
并且用的前缀和的思想,\(add[l]\)表示从第\(l\)层往下更新的值,由于他要求更新的是一定范围内的节点。所以超过\(l+d\)层的就不更新了。
每一个节点只有可能被他的祖先或者自己更新,所以当dfs到他的时候,他的值就是他的结果了。
然后继续更新他的子孙。这里假设是二叉树,左子树更新完了之后,更新右子树的时候要左边的是更新不到右边的,所以要把add数组给恢复回来。相当于回溯。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
using namespace std;
typedef long long LL;
#define N 100010
#define pi 3.1415926535 int n, m;
const int maxn = 3e5 + ;
vector<int>edg[maxn];
vector<pair<int, int> >op[maxn];
LL ans[maxn], add[maxn]; void dfs(int v, int fa, int h, LL sum)
{
for(int i = ; i < op[v].size(); i++){
int l = h, r = h + op[v][i].first;
add[l] += op[v][i].second;
if(r + < maxn)add[r + ] -= op[v][i].second;
}
sum += add[h];
ans[v] = sum;
for(int i = ; i < edg[v].size(); i++){
if(edg[v][i] == fa)continue;
else{
dfs(edg[v][i], v, h + , sum);
}
}
for(int i = ; i < op[v].size(); i++){
int l = h, r = h + op[v][i].first;
add[l] -= op[v][i].second;
if(r + < maxn)add[r + ] += op[v][i].second;
}
} int main()
{
while(scanf("%d", &n) != EOF){
for(int i = ; i <= n; i++){
edg[i].clear();
op[i].clear();
add[i] = ;
ans[i] = ;
}
for(int i = ; i < n; i++){
int x, y;
scanf("%d%d", &x, &y);
edg[x].push_back(y);
edg[y].push_back(x);
}
scanf("%d", &m);
for(int i = ; i < m; i++){
int v, d, x;
scanf("%d%d%d", &v, &d, &x);
op[v].push_back(make_pair(d, x));
} dfs(, , , );
for(int i = ; i <= n; i++){
printf("%I64d", ans[i]);
if(i != n)printf(" ");
else printf("\n");
}
} return ;
}
Educational Codeforces Round 54 ---1076ABCDE的更多相关文章
- Educational Codeforces Round 54 (Rated for Div. 2) D:Edge Deletion
题目链接:http://codeforces.com/contest/1076/problem/D 题意:给一个n个点,m条边的无向图.要求保留最多k条边,使得其他点到1点的最短路剩余最多. 思路:当 ...
- Educational Codeforces Round 54 E. Vasya and a Tree(树上差分数组)
https://codeforces.com/contest/1076/problem/E 题意 给一棵树(n<=3e5),m(3e5)次查询,每次查询u,d,x,表示在u的子树中,给距离u&l ...
- Educational Codeforces Round 54 [Rated for Div. 2] (CF1076)
第一次在宿舍打CF 把同宿舍的妹子吵得不行... 特此抱歉QAQ A 题意:给定一个字符串, 最多删掉一个字符,使得剩余字符串字典序最小 n<=2e5 当然"最多"是假的 删 ...
- Educational Codeforces Round 54 (Rated for Div. 2) Solution
A - Minimizing the String solved 题意:给出一个字符串,可以移掉最多一个字符,在所有可能性中选取一个字典序最小的. 思路:显然,一定可以移掉一个字符,如果移掉的字符的后 ...
- Educational Codeforces Round 54
这套题不难,但是场上数据水,导致有很多叉点 A. 因为是让求删掉一个后字典序最小,那么当a[i]>a[i+1]的时候,删掉a[i]一定最优!这个题有个叉点,当扫完一遍如果没有满足条件的,就删去最 ...
- Educational Codeforces Round 54 (Rated for Div. 2) DE
D 给出一个无向图,需要删去一些边,想知道最后能有多少个点到1的距离还是过去那么短 如果求一个最短路,然后从删边的角度看,看起来很难做,但是如果从零开始加边就会有做法,如同prim那样,先加入和1直接 ...
- Educational Codeforces Round 54 (Rated for Div. 2) ABCD
A. Minimizing the String time limit per test 1 second memory limit per test 256 megabytes Descriptio ...
- Codeforces Educational Codeforces Round 54 题解
题目链接:https://codeforc.es/contest/1076 A. Minimizing the String 题意:给出一个字符串,最多删掉一个字母,输出操作后字典序最小的字符串. 题 ...
- Educational Codeforces Round 54 (Rated for Div. 2) D Edge Deletion (SPFA + bfs)
题目大意:给定你一个包含n个点m条边的无向图,现在最多在图中保留k条边,问怎么删除多的边,使得图中良好的节点数最多,求出保留在图中的边的数量和编号. 良好的节点定义为:删除某条边后该点到点1的最短距离 ...
随机推荐
- 码云git使用一(上传本地项目到码云git服务器上)
主要讲下如果将项目部署到码云git服务器上,然后使用studio导入git项目,修改本地代码后,并同步到码云git上面. 首先:我们在码云上注册账号并登陆.官网(https://git.oschina ...
- grep console
FF6464 9F6B00 8A8A00 4B5E76 8A7674 980B4F 980B4F
- window.open打开新窗口 参数
1,基本描述 oNewWindow = window.open( sURL , sName , sFeatures, bReplace) window.open在打开一个窗口(其url为sURL)后, ...
- unity中导入插件时报错处理办法
错误如下: Unhandled Exception: System.TypeLoadException: Could not load type 'System.ComponentModel.Init ...
- 【阅读笔记】《C程序员 从校园到职场》第五章 内存操作
参考: 让你提前认识软件开发(8):memset()与memcpy()函数 https://blog.csdn.net/zhouzxi/article/details/22478081 让你提前 ...
- RabbitMQ 设置消息的优先级
在RabbitMQ中,可以设置消息的优先级,也就相当于在队列中置顶某条消息,让某个消息优先得到处理的功能. 既然是设置消息的优先级,那么就是针对生产者,也就是消息发布端. 设置消息的优先级一共有2个步 ...
- JVM运行时内存区域
JVM运行java程序时会将内存划分为若干个不同的数据区域: (1)程序计数器: 1.占用内存空间不大. 2.程序计数器相当于JVM所执行的字节码(jvm指令)的“行号指示器”,通过程序计数器的“值” ...
- ubuntu多显示器单触摸屏校准
多显示器单触摸屏屏幕校准 0.触摸屏重定向 sudo xinput map-to-output 13 DP1 #将触摸屏映射到指定的显示器 其中:13为触摸屏设备id,可通过 xinput命令查看 ...
- asp.net mvc 实现简单的实时消息推送
因为项目需要,需要在网页上实现消息的推送.在百度上搜索了一下,发现实现网页上的消息推送,可以使用asp.net 中的SignalR类库,当然也可以使用H5的WebSocket Ajax的轮回.当然此 ...
- 使用FileResult导出Excel数据文件
用的是Html拼接成Table表格的方式,返回 FileResult 输出一个二进制的文件. 第一种:使用FileContentResult // 通过使用文件内容,内容类型,文件名称创建一个File ...