2018 USP-ICMC
简单题 B D F L
中等难度题 E I
更难一点得题 A C G
难题 H K J
这个题目很简单,不过我的方法有点点小问题,不过可以改进一下就应该没什么问题了。
这个题目就是让你判断不断把最后一位移到最前面来组成的新数字会不会有比原来小的,
这个题目就先判断后面有没有数字比第一个小,有的话就不对了
除了这个还有一种可能就是后面的数字和原来第一位的数字一样,那么就需要判断和第一位一样的数字后面跟的数和第一位跟的数哪个更大。
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <queue>
#include <string>
#include <vector>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 5e5 + ;
char s[maxn];
int main()
{
int n;
cin >> n;
cin >> s;
int num = ;
int ok = ;
for(int i=;i<n;i++)
{
if (s[i] < s[]) ok = ;
if(s[i]==s[])
{
num = ;
int x = i, y = ;
while(s[x]==s[y])
{
x = (x + ) % n;
y = (y + ) % n;
num++;
if (num > ) break;
}
if (s[x] < s[y]) ok = ;
}
}
if (ok==) printf("Yes\n");
else printf("No\n");
return ;
}
这个就是给你一些人对于数字的喜好,让你求出最后他们都喜欢的数字有多少
先给你n代表有n个人
每一个人一列,如果第一个数字是1 代表这是说这个人喜好的数字,如果是2代表这是说这个人讨厌的数字
这个题目比较简单,因为数字很大就需要用map来存,不过map也不需要很大,
两个map 如果有1出现的人,那就只需要一个map来存,没有就需要第二个来存2的数字。
如果有1出现,那么就把第一个人当作基准,如果后面的人喜好(1)就++,不喜欢就删去(2)
如果只有2 那就用另一个map来判断就可以了。
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <queue>
#include <map>
#include <string>
#include <vector>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 5e5 + ;
const ll mx = 1e18;
map<ll, int>mp;
map<ll, int>two;
int main()
{
int n;
scanf("%d", &n);
ll num = ;
int nu1 = , nu2 = ;
int first = ;
for(int i=;i<=n;i++)
{
int opt, len;
scanf("%d%d", &opt, &len);
if(opt==&&first==)
{
nu1++;
first = ;
for(int j=;j<=len;j++)
{
ll x;
scanf("%lld", &x);
mp[x]++;
//printf("1 mp[%lld]=%d\n", x, mp[x]);
}
}
else if(opt==)
{
nu1++;
for(int j=;j<=len;j++)
{
ll x;
scanf("%lld", &x);
if (mp[x])
{
mp[x]++;
// printf("2 mp[%lld]=%d\n", x, mp[x]);
}
}
}
else if(opt==)
{
nu2++;
for(int j=;j<=len;j++)
{
ll x;
scanf("%lld", &x);
if (mp[x]) mp[x] = ;
two[x]++;
}
}
}
if(nu1)
{
map<ll, int>::iterator p;
for(p=mp.begin();p!=mp.end();p++)
{
//printf("%lld %d\n", p->first, p->second);
if (p->second >= nu1) num++;
}
printf("%lld\n", num);
return ;
}
ll ans = ;
map<ll, int>::iterator p;
for (p = two.begin(); p != two.end(); p++) ans++;
printf("%lld\n", mx - ans);
return ;
}
这个题目题意读懂就好了,这个就是从起点到终点只可以用最多n步,每一个位置都可以重复走,然后问你从起点到终点可以有多少种不同的步数。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
const int Max = 1e5 + ;
const int inf = 0x3f3f3f3f; int main()
{
ll n, x1, x2, y1, y2;
scanf("%lld%lld%lld%lld%lld", &n, &x1, &y1, &x2, &y2);
ll m = abs(x1 - x2) + abs(y1 - y2);
if (m > n)
{
printf("0\n");
}
else if (m == )
{
printf("%lld\n", (n - m) / );
}
else
{
printf("%lld\n", (n - m) / + );
}
return ;
}
这个就是一棵树,给了你起点,问你从这一点开始不重复的走能走到的最多的点是多少。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int Max = 1e5 + ;
const int inf = 0x3f3f3f3f; vector<int> v[Max];
bool vis[Max]; //是否以走
int depth[Max]; int build(int now)
{
queue<int>q;
q.push(now);
vis[now] = true;
depth[now] = ;
int cnt = ;
while (!q.empty())
{
int s = q.front();
q.pop();
vis[s] = true;
for (int i = ; i < v[s].size(); i++)
{
int e = v[s][i];
if (!vis[e])
{
depth[e] = depth[s] + ;
q.push(e);
}
}
cnt = max(cnt, depth[s]);
}
return cnt;
} int main()
{
int n, now;
while (scanf("%d%d", &n, &now)!=EOF)
{
memset(vis, , sizeof(vis));
for (int i = ; i <= n; i++)
{
v[i].clear();
}
for (int i = ; i < n - ; i++)
{
int s, e;
scanf("%d%d", &s, &e);
v[s].push_back(e);
v[e].push_back(s);
}
printf("%d\n", build(now));
}
return ;
}
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <vector>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 1e5 + ;
int a[maxn];
int dp[][];//表示已经处理了前面的i个,然后还可以处理j次需要消耗的能量。
int n, m; int cul(int x)
{
return x * (x + ) / ;
} int dfs(int p,int k)
{
if (k < ) return inf;//如果k<0这个是不应该出现的情况,如果出现了,说明交换的次数超了,所以用inf表示不可能
if (p >= n) return ;//如果到达p==n的同时k>=0,这个就说明这个情况是合理的,而且p==n的时候就不会需要消耗能力了。
if (dp[p][k] != -) return dp[p][k];
if (a[p] == ) return dfs(p + , k);//如果这一个值它是0就不需要做过多的考虑
int i = ;
dp[p][k] = inf;
for (i = p; i < n&&a[i] == ; i++)
{
dp[p][k] = min(dp[p][k], dfs(i + , k - ) + cul(i - p));//转移方程
}
dp[p][k] = min(dp[p][k], dfs(i + , k) + cul(i - p));//这个是考虑在出现0之前的每一个1都不删去。
return dp[p][k];
} int main()
{
scanf("%d%d", &n, &m);
for (int i = ; i < n; i++) scanf("%1d", &a[i]);
memset(dp, -, sizeof(dp));
for(int i=;i<=n;i++)
{
if(dfs(,i)<=m)
{
printf("%d\n", i);
return ;
}
}
}
题目大意就是给你一个人他的好朋友,定下规则,就是这个人去宴会的唯一原因就是他好朋友去了,但是他好朋友去了他不一定去,
意思就是如果一个人去了,那么他的好朋友一定去了,但是如果他的好朋友去了他不一定去,这个不会成环,
举个例子 如果a是b的好朋友那么b就不是a的好朋友。
这个题目就是利用这个关系建树,如果在同一棵树上一个人的深度比另一个人的浅,那就说明这个人会去,反之则不会去,这个树自己画一下就明白了。
但是这里有很多棵树,这个就很麻烦。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 1e5 + ;
int l[maxn], r[maxn];
int head[maxn];
bool vis[maxn];
struct node
{
int u, v, nxt;
}exa[maxn];
int cnt = ;
void add(int u,int v)
{
exa[cnt].u = u;
exa[cnt].v = v;
exa[cnt].nxt = head[u];
head[u] = cnt++;
}
int tot = ;
void dfs(int u)
{
l[u] = ++tot;
for(int i=head[u];i!=-;i=exa[i].nxt)
{
dfs(exa[i].v);
}
r[u] = ++tot;
} int main()
{
int n, m;
memset(vis, , sizeof(vis));
memset(head, -, sizeof(head));
scanf("%d%d", &n, &m);
for(int i=;i<n;i++)
{
int x;
scanf("%d", &x);
if (x != -)
{
add(x, i);
vis[i] = ;
}
}
for(int i=;i<n;i++)
{
if (!vis[i]) dfs(i);
}
while(m--)
{
int u, v;
scanf("%d%d", &u, &v);
if (l[u] >= l[v] && r[u] <= r[v]) printf("Yes\n");
else printf("No\n");
}
return ;
}
A. Nicoleta and the circle of kids
这个题目是求最大生成树的所有边之和,和最小生成树差不多,但是因为这个数据太大无法建图,所以不能用那种方法。
先说说这个是怎么建图的,这个就是任意一个人他可以连所有离他的距离小于等于k的人,他们两个直接的边的权值为他们的距离。
但是既然是求最大生成树,那么就肯定边越长越好,所以我们都取k。
例如,我们任选一个人a开始,那么他会连到a+k 然后a+k这个人又会往后面连 a+k就可以连到 a+2k这个人 以此类推 就是一个点集 a+m*k
这个题目有难就难在这里有一个取模操作意思就是 n=3 k=2 那么第0个人是不是会连到第二个人 然后第二个人+2对n取模是不是会连到第1个人。
所以这个点集为 (a+m*k)%n 这个取模操作就让题目变得复杂了,我们可以消除这个取模操作
就是 a+m1*z=a+m*k%n 这个z=gcd(n,k) 所以就是以一个点为起点就有 n/z这么多个人可以连在一起,他们直接的权值都是k
然后一共最多有z个这样的圈子,这些圈子都连了边了,只有圈子之间没有连边了,可以证明的是,这些圈子之间无法连长度为k的边,但是可以连长度为k-1的边。
#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
typedef long long ll; ll gcd(ll a,ll b)
{
return b == ? a : gcd(b, a%b);
} int main()
{
ll n, k;
cin >> n >> k;
ll z = gcd(n, k);
ll ans = k * (n / z - )*z + (k - )*(z - );
printf("%lld\n", ans);
return ;
}
2018 USP-ICMC的更多相关文章
- (寒假开黑gym)2018 USP Try-outs
layout: post title: (寒假开黑gym)2018 USP Try-outs author: "luowentaoaa" catalog: true tags: m ...
- 2018 USP Try-outsF - Optimizing Transportation in Portugal
题意:给你一副无向图,求使s到t删掉一条的最短路最大的长度 题解:先预处理s,t到每个点的最短路,二分答案,对于一条边,如果选中这条边,那么对于s->u+u->v+v->t或者s-& ...
- 2018. The Debut Album
http://acm.timus.ru/problem.aspx?space=1&num=2018 真心爱过,怎么能彻底忘掉 题目大意: 长度为n的串,由1和2组成,连续的1不能超过a个,连续 ...
- Math.abs(~2018),掌握规律即可!
Math.abs(~2018) 某前端群的入门问题长姿势了,一个简单的入门问题却引发了我的思考,深深的体会到自己在学习前端技术的同时忽略遗忘了一些计算机的基础知识. 对于 JS Math对象没什么可说 ...
- 肖秀荣8套卷2018pdf下载|2018肖秀荣冲刺8套卷pdf下载电子版
肖秀荣8套卷2018pdf下载|2018肖秀荣冲刺8套卷pdf下载电子版 下载链接: https://u253469.ctfile.com/fs/253469-229815828
- 2018年的UX设计师薪酬预测,你能拿多少?
以下内容由Mockplus团队翻译整理,仅供学习交流,Mockplus是更快更简单的原型设计工具. 一个经验丰富的设计师完全可以根据地区和专业来可以预期薪酬之间的差距,其中悬殊最高可达80K. 本 ...
- Hello 2018, Bye 2017
2017年过去了,过去一年经历了太多,改变了好多好多,可以说人生进入了另一个阶段,有可能是成熟吧. 回顾2017 去年换了新工作,离开了将近工作了8年的公司,不带走一丝云彩,为其任劳任怨,最后没有任何 ...
- New Life With 2018
2017年转眼过去了.对自己来说.这一大年是迷茫和认知的一年.我的第一篇博客就这样记录下自己的历程吧 一:选择 从进入这一行到现在已经一年多了,2016年11月份就像所有的应届毕业生一样,都贼反感毕业 ...
- 2017 年终总结 & 2018 年度计划
不立几个 Flag,都不知道怎么作死 2017 年度计划完成情况: 1.健身时间不少于350天: 未完成 中断了22天,实际运动 343天 2.至少每个月看一本书: 及格 <切尔诺贝利的 ...
- [总结]-2018 w1
不想总结 2017,过去的就过去吧,不过自己在 2017 年还是收获了很多,最重要的就是赚钱.赚钱还是需要两把刷子,所以,2018 的小目标就是学习数据分析和机器学习.希望自己在这两个领域能搞点事情. ...
随机推荐
- iOS获取剩余存储空间
//ios获取剩余存储空间 -(void)usedSpaceAndfreeSpace{ NSString* path = [NSSearchPathForDirectoriesInDomains(NS ...
- 假的数论gcd,真的记忆化搜索(Codeforce 1070- A. Find a Number)
题目链接: 原题:http://codeforces.com/problemset/problem/1070/A 翻译过的训练题:https://vjudge.net/contest/361183#p ...
- 【Java】Junit单元测试
什么是单元测试? 单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证. 对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Ja ...
- d3.js v4曲线图的拖拽功能实现Zoom
zoom缩放案例 源码:https://github.com/HK-Kevin/d...:demo:https://hk-kevin.github.io/d3...: 原理:通过zoom事件来重新绘制 ...
- 机器学习新手项目之N-gram分词
概述 对机器学习感兴趣的小伙伴,可以借助python,实现一个N-gram分词中的Unigram和Bigram分词器,来进行入门, github地址 此项目并将前向最大切词FMM和后向最大切词的结果作 ...
- DOS事件
1 onblur 失去焦点 2 onchange 改变 3 onkeyup 按键弹起 4 onmouse over 鼠标移上去 5 onmouse leave 鼠标离开 6 onmo ...
- 【题解】POJ3041 Asteroids - 图论 - 二分图匹配
声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 POJ3041 Asteroids 题目描述 假如你现在正处在一个 \(N*N\ ...
- 聊聊JavaScript在工作中常用的方法(一)
一.字符串转数组(split方法) 废话少说,直接上代码: //例子1 var str="abc,def,ghi"; var strArray=str.split(",& ...
- 技术周刊 · 0202 年了,你还不学一下 WASM 么?
蒲公英 · JELLY技术周刊 Vol.04 「蒲公英」期刊全新升级--JELLY技术周刊!深度挖掘业界热点动态,来自团队大咖的专业点评,带你深入了解团队研究的技术方向. 登高远眺 天高地迥,觉宇宙之 ...
- 二, 连接Oracle 二
一,sqlplus操作 文件操作命令 1.start和@ 说明: 运行sql脚本 案例: sql>@ home/a.sql或是sql>start home/a.sql 2.edit 说明: ...