ACM团队周赛题解(1)
这次周赛题目拉了CF315和CF349两套题。
因为我代码模板较长,便只放出关键代码部分
#define ll long long
#define MMT(s,a) memset(s, a, sizeof s)
#define GO(i,a,b) for(int i = (a); i < (b); ++i)
#define GOE(i,a,b) for(int i = (a); i <= (b); ++i)
#define OG(i,a,b) for(int i = (a); i > (b); --i)
#define OGE(i,a,b) for(int i = (a); i >= (b); --i)
这是代码中的几个宏定义,需要拿代码修改这个几个就行了,若是用到代码其他定义部分,会在代码中额外添加。
这里也只是部分题解。
A - Cinema Line (CF-349A)
题意很简单,就是说你是售票员,门票价格25元,有n个人来买票,钱只有25,50,100三种,最开始你没有钱,问你是否可以完成售票过程,即每个人都有足够的零钱找他,按顺序购票。
题目思路模拟即可。
int main(){
ios_base::sync_with_stdio(false), cout.tie(), cin.tie();
int n,a,flag = ,tot1 = ,tot2 = ,tot3 = ;
cin>>n;
GO(i,,n){
cin>>a;
if(a == ){
tot1++;
}
else if(a == ){
if(tot1 > ){
tot1--;
tot2++;
}
else
flag = ;
}
else if(a == ){
if(tot2 > && tot1 > ){
tot2--,tot1--;
tot3++;
}
else if(tot1 > ){
tot1-=;
tot3++;
}
else
flag = ;
}
}
if(flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
return ;
}
B - Color the Fence (CF-349B)
题目意思就是最开始有n,然后选取第i个数就需要花费a[i],问最大能够成的数。
题目思路:首先需要保证位数最大,所以先找到最小值min,n/min即为最大位数,然后对于每一位,从9-1往回找输出。值得注意的是,可能你选取某个数会使得位数减少,所以选取数还得判断是否会影响位数。双重循环贪心。
int n,a[] = {};
int flag = ,ii;
int main(){
ios_base::sync_with_stdio(false), cout.tie(), cin.tie();
cin>>n;
int minn = INT_MAX;
GOE(i,,){
cin>>a[i];
if(a[i] < minn)
minn = a[i];
}
if(minn > n){
cout << - << endl;
return ;
}
int cnt = n / minn;
OGE(i,cnt,){
OGE(j,,){
if(n >= a[j] && (n-a[j]) / minn >= i-){
cout << j;
n -= a[j];
break;
}
}
}
cout << endl;
return ;
}
C - Mafia(CF-349C)
题目意思就是n个人进行Mafia的游戏,游戏规则就是选取一个人当裁判(类似狼人杀),其他n-1个人进行游戏,如果某人某局为裁判,则不计入他的游戏对局数。问要保证每个人i都玩了a[i]局游戏。
题目思路:首先要保证最大值max = max(a[i])玩完,所以游戏至少要玩max轮,在这max轮对局中,当某个人玩成了他的a[i]局,那么剩下的max-a[i]局他就可以当裁判为其他人服务。
所以令sum = Σ(max - a[i])。
当sum >= max时,说明有足够的轮数可以让非最大值的人当裁判去完成最大值的max轮,这种情况只需要玩max局即可。
当sum < max时,则需要额外的轮数让其他人为最大值的人当裁判,而每一轮有n-1个人可以当裁判。这种情况就玩(max - sum)/(n-1)+max即可。
同理这道题也可以二分,因为每局都有n-1个人可以当裁判为剩下的一个人服务。那么则从max —— Σ(a[i])二分选取cnt*(n-1) >= sum即可。
int a[];
int main(){
ios_base::sync_with_stdio(false), cout.tie(), cin.tie();
int n,maxx = INT_MIN;
ll sum = ;
cin>>n;
GO(i,,n){
cin>>a[i];
maxx = max(a[i],maxx);
}
GO(i,,n)
sum += maxx - a[i];
if(sum >= maxx)
cout << maxx << endl;
else{
int cnt = ;
while(sum < maxx){
cnt++;
sum += n-;
}
cout << maxx+cnt << endl;
}
return ;
}
D - Apple Tree(CF-349D)
题意就是有一颗苹果树,根节点为1,然后保证非叶子节点的值都是0(就是树枝上不会有苹果,很好理解),叶子节点的值是a[i],然后现在要使这颗树变得平衡,平衡的定义为,每个非叶子节点的所有子节点值相同(就是说某个树杈的所有树枝包含的苹果相同)。
题目思路:对于每一个结点u,要知道它的总分支数r[u]及现在所拥有的权值和val[u],因为不同子树总分支数不一定相同,故结点u每次减少的值需要是其所有子树分支的最小公倍数,而且对于u的子树也需要保证平衡,故u点每次需减去的值 = lcm * 儿子个数,值得注意的是lcm可能会爆long long,这种情况我们可以认为这个树平衡当且仅当所有的苹果都被拿走,即全部去掉。
那么对于任意一个节点,先计算这个节点可拿走的苹果数,再计算苹果数目的上界,贪心选取最大重量更新节点情况。
代码还有额外的宏定义
#define PB push_back
const ll INFF = 0x3f3f3f3f3f3f3f3f;
template<typename T>
inline T gcd(T a, T b){ return b==0 ? a : gcd(b,a%b); }
template<typename T>
inline T lcm(T a, T b){ if(a*b > INFF) return 0; return a / gcd(a,b) * b; }
const int maxn = <<; ll v[maxn],dp[maxn],dis[maxn];
ll sum = ;
vector<int> Edge[maxn];
bool flag; void Add(int l,int r){
Edge[l].PB(r);
Edge[r].PB(l);
} void dfs(int st,int fa){
dp[st] = v[st],dis[st] = ;
int cnt = ;
for(auto it : Edge[st]){
if(it == fa)
continue;
cnt++;
dfs(it,st);
int temp = lcm(dis[st],dis[it]);
if(temp)
dis[st] = temp;
else
dis[st] = , flag = ;
dp[st] += dp[it];
}
for(auto it : Edge[st]){
if(it == fa)
continue;
dp[st] = min(dp[st],dp[it] - dp[it]%dis[st]);
}
(cnt == ) && cnt++;
dp[st] *= cnt, dis[st] *= cnt;
} int main(){
ios_base::sync_with_stdio(false), cout.tie(), cin.tie();
int n,l,r;
cin>>n;
GOE(i,,n){
cin>>v[i];
sum += v[i];
}
GO(i,,n){
cin>>l>>r;
Add(l,r);
}
flag = ;
dfs(,);
if(!flag)
cout << sum << endl;
else
cout << sum - dp[] << endl; return ;
}
F - Sereja and Bottles(CF-315A)
题意就是n个瓶子,a[i]瓶可以打开其他的第b[i]瓶,问最后剩下多少瓶子没有打开。
题目思路:标记模拟即可
int main(){
ios_base::sync_with_stdio(false), cout.tie(), cin.tie();
int n,cnt();
int a[],b[],vis[] = {};
cin>>n;
GOE(i,,n)
cin>>a[i]>>b[i];
GOE(i,,n){
GOE(j,,n){
if(i != j && a[j] == b[i])
vis[j] = ;
}
}
GOE(i,,n){
if(vis[i])
cnt++;
}
cout << n - cnt << endl;
return ;
}
G - Sereja and Array(CF-315B)
题意就是三种操作.
1 就是把第x个元素变成v;
2 就是把所有元素加上v;
3 即使输出第x个元素的值;
题目思路:1,3操作容易实现,主要是2操作,总不能遍历把每个值加上v,因为题目说了是所有值加上v,所以只需要用一个数记录v的和,输出是加上这个就行,同时需要因为有1操作,所以还需要开额外一个数组记录当某个值改变时,存取当前的v总和,输出再减去这个值即可。
int n,m,temp = ;
int a[],dis[];
int x,y,z; int main(){
ios_base::sync_with_stdio(false), cout.tie(), cin.tie();
cin>>n>>m;
GOE(i,,n)
cin>>a[i];
GO(i,,m){
cin>>x;
if(x == ){
cin>>y>>z;
dis[y] = temp;
a[y] = z;
}
else if(x == ){
cin>>y;
temp += y;
}
else if(x == ){
cin>>y;
cout << a[y] + temp - dis[y] << endl;
}
} return ;
}
H - Sereja and Contest(CF-315C)
题意就是有n个数字,当f(a[i])小于k时删除这个数,输出其位置,再从新计算。
f(i) = Σ(a[j]*(j-1) - (n-i)*a[i]);
题目思路:第一轮删除了a[i],那么下一轮删除的数的位置,一定时大于i的。
这个公式可以变成(j-1)* Σ(a[j]) - (j-1)*(n-i)*a[i],可以发现前半部分就是一个前缀和,所以过程中维护n的大小动态修改。
int n,k;
ll a[]; int main(){
ios_base::sync_with_stdio(false), cout.tie(), cin.tie();
cin>>n>>k;
GOE(i,,n)
cin>>a[i];
ll now(),tot(),temp(n);
GOE(i,,n){
now += a[i-]*tot;
if(now - (temp-i+(n-temp))*a[i]*(i--(n-temp)) < k){
temp--;
now -= a[i]*tot;
cout << i << endl;
}
else
tot++;
}
return ;
}
I - Sereja and Periods(CF-315D)
题目意思就是两个串分别是[a,b],[c,d],运算规则就是b个a相连接,例如[abc,2] = abcabc;
然后问你[a,b]这个串中出现了几次[c,d]。
题目思路:KMP找循环节。用cnt[i]记录当前开始以c串的i位置找,经过一个a串后,会经过几个c串,nxt记录当前开始以c串的i位置开始找,经过一个a串后,匹配的位置会到什么地方。每次对于a串都是从0~lena找,因为走完一个a串后,下一条又从0开始了。
1e7,单层循环,没问题。
int b,d,cnt[] = {},nxt[];
string a,c;
int main(){
ios_base::sync_with_stdio(false), cout.tie(), cin.tie();
cin>>b>>d>>a>>c;
int lenc = c.size(),lena = a.size();
GO(i,,lenc){
int temp = i;
GO(j,,lena){
if(a[j] == c[temp]){
temp++;
if(temp == lenc)
cnt[i]++, temp = ;
}
}
nxt[i] = temp;
}
int j = ;
ll sum = ;
GOE(i,,b){
sum += cnt[j];
j = nxt[j];
}
cout << sum/d << endl;
return ;
}
暂时只补了这么多题目。太难了暂时还补不了,望谅解。
ACM团队周赛题解(1)的更多相关文章
- ACM团队周赛题解(3)
940和822两套div.2 老规矩 #define MAXN 1000000+5#define MOD 1000000007#define PI (acos(-1.0))#define EPS 1e ...
- ACM团队周赛题解(2)
拉了CF583和CF486的两套div2题目 还是先贴宏定义部分 #define MAXN 1000000+5#define MOD 1000000007#define PI (acos(-1.0)) ...
- 2015浙江财经大学ACM有奖周赛(一) 题解报告
2015浙江财经大学ACM有奖周赛(一) 题解报告 命题:丽丽&&黑鸡 这是命题者原话. 题目涉及的知识面比较广泛,有深度优先搜索.广度优先搜索.数学题.几何题.贪心算法.枚举.二进制 ...
- ACM团队招新赛题解
标程代码全部为C语言编写.代码中的#if LOCAL_ 至#endif为本地一些调试内容,可以忽略. Xenny的A+B(1)[容易][签到] 签到题,做不出的话可能你有点不太适合ACM了. Xenn ...
- SUST_ACM_2019届暑期ACM集训热身赛题解
问题A:Hello SUST! 知识点:基本输入输出 C/C++: #include <stdio.h> int main() { int n; scanf("%d", ...
- FJUT2019暑假第二次周赛题解
A 服务器维护 题目大意: 给出时间段[S,E],这段时间需要人维护服务器,给出n个小时间段[ai,bi],代表每个人会维护的时间段,每个人维护这段时间有一个花费,现在问题就是维护服务器[S,E]这段 ...
- 「POJ3436」ACM Computer Factory题解
题意: 有很多台机器,可以把物件从一种状态改装成另一种状态,初始全为\(0\),最终状态全为\(1\),让你可以拼凑机器,请问最大总性能为多少,且要求输出方案. 题解: 这道题是真的水啊,我不想写太多 ...
- ACM: 限时训练题解-Runtime Error-二分查找
Runtime Error Bahosain was trying to solve this simple problem, but he got a Runtime Error on one ...
- ACM: 限时训练题解-Heavy Coins-枚举子集-暴力枚举
Heavy Coins Bahosain has a lot of coins in his pocket. These coins are really heavy, so he always ...
随机推荐
- 面试java_后端面经_5
情话部分: 小姐姐:为什么有很多人在感情中付出很多,却得不到想要的结果? 你答:我听过一个这样的故事:讲的是蚯蚓一家人,有一天,蚯蚓爸爸特别无聊,就把自己切成了俩段愉快的打羽毛球去了,蚯蚓妈妈见状,把 ...
- 敏捷之旅--携程Scrum Master 新官上任三把火?
随着敏捷在国内的推行,越来越多的公司和组织开始使用敏捷领导团队. 敏捷团队如雨后春笋之势涌现. 敏捷教练的团队也越来越壮大. 原先只需要一个敏捷教练就能搞定,但是随着团队越来越多,我们难免会将 ...
- .net打杂工程师的面试感想和总结
上个月26号辞职了,今天开始第一场面试,随便写写感想,后面还会继续分享一些感想 前言 这个时候找工作是不是找死? 开门见山吧,95年的,之前做过两份工作,第一家公司在做了2年2个月,在北京,也就是去年 ...
- 存储型XSS的发现经历和一点绕过思路
再次骚扰 某SRC提现额度竟然最低是两千,而已经有750的我不甘心呐,这不得把这2000拿出来嘛. 之后我就疯狂的挖这个站,偶然发现了一个之前没挖出来的点,还有个存储型XSS! 刚开始来到这个之前挖过 ...
- Unity之SDK接入(Unity与Android通信)
首先介绍一点关于Android与unity通信的知识: 完成通信主要靠unity中的class.jar包(在unity的安装目录下). 在unity中调用android的方法: jo.call(&qu ...
- ForkJoinPool 分支/合并框架
ForkJoinPool 分支/合并框架 一.Fork/Join框架简介 Fork/Join 框架就是在必要的情况下,将一个大任务,进行拆分(fork)成若干个小任务(拆到不可再拆时),再将一个个的小 ...
- Leetcode之深度优先搜索&回溯专题-491. 递增子序列(Increasing Subsequences)
Leetcode之深度优先搜索&回溯专题-491. 递增子序列(Increasing Subsequences) 深度优先搜索的解题详细介绍,点击 给定一个整型数组, 你的任务是找到所有该数组 ...
- svn checkout 单个文件
$ svn co --depth=empty file:///usr/local/svn/calc calc_new $ cd calc_new $ svn up readme.txt 其中,calc ...
- MSIL实用指南-创建对象
创建对象用Newobj指令,它的操作是创建一个新的对象或值类型,并将对象引用的新实例到计算堆栈上.格式是Newobj <构造函数>实例: ilGenerator.Emit(OpCodes. ...
- webpack.config.js配置实例
const path = require('path') const HtmlWebPackPlugin = require('html-webpack-plugin') // 导入 在内存中自动生成 ...