Educational Codeforces Round 80 A-E简要题解
contest链接:https://codeforces.com/contest/1288
A. Deadline
题意:略
思路:根据题意 x + [d/(x+1)] 需要找到一个x使得上式小于等于n,即x + [d/(x+1) ] <=n,不等式两边同时+1得 x+1 + [d/(x+1)] <=n + 1当且仅当(x+1)2 = d时,式子左边最小,所有只需要判断一下最小值是否<=n+1就可以知道该不等式是否存在x满足题意了,即找到x = √d - 1,判断一下即可。
AC代码:
#include<iostream>
#include<vector>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
int main(){
int t;
cin>>t;
while(t--){
ll n,d;
cin>>n>>d;
if(d<=n){
cout<<"YES"<<endl;
continue;
}
ll t = sqrt(d) - ;
ll ans = t + (d/(t+));
if(d%(t+)!=) ans++;
if(ans<=n){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
return ;
}
B. Yet Another Meme Problem
题意:题目定义了一个公式,a×b + a + b = conc(a,b),给出a,b的取值范围,求满足此公式条件的所有pari(a,b)个数
思路:只有当b = 9,99,999....9999999的时候,a为任意值,才满足以上等式,然后判断一下b范围内覆盖的9,99,999...........9999999999即可
AC代码:
#include<iostream>
#include<vector>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
int main(){
int t;
cin>>t;
while(t--){
ll a,b;
cin>>a>>b;
ll tb = b;
int cnt = ;
while(b){
b/=;
cnt++;
}
ll s = pow(,cnt)-;
// cout<<s<<endl;
if(tb != s) cnt--;
ll ans = a*cnt;
cout<<ans<<endl;
}
return ;
}
C. Two Arrays
题意:给定一个数n和一个数m,让构建两个数组a和b满足条件,1.数组中所有元素的取值在1~n之间,a和b数组长度是m。2. a数组是单调不递减的,b数组是单调不递增 3. 任意的位置i,有ai<=bi
思路:可以组合数学做,也可以dp,以下为dp做法。首先如果把a、b两个数组合并成 a1,a2,a3,.......am,bm,bm-1,bm-2,bm-3...........b3,b2,b1,会发现整个数列是单调不递减的,那么就可以dp做了,
dp[i][j]表示第i个位置可以放 大于等于 j 的方案数 ,那么转移方程就是 dp[i][j] = dp[i-1][j] + dp[i][j+1]
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
const int maxm = ;
const int maxn = 1e3+;
const int mod = 1e9+;
ll dp[maxm*][maxn];
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i = ;i<=n;i++) dp[][i] = ;
for(int i = ;i<=*m;i++){
for(int j = n;j>=;j--){
dp[i][j] = (dp[i][j+] + dp[i-][j])%mod;
}
}
ll ans = ;
for(int i = ;i<=n;i++){
ans = (ans+dp[*m][i])%mod;
}
printf("%d",ans);
return ;
}
D. Minimax Problem
题意:给定n个数组,长度为m,从n中数组挑选两个数组,两个数组中的每一位取两者的最大值组成一个新的数组,新数组中的最小值记为c,所有组合中c的最大值
思路:思路:题目中m的范围只有8,数组中元素的范围是1e9,显然m的范围非常特殊,似乎可以把数组用二进制的形式进行状态压缩,这里采用二分答案的方法。二分范围是数组元素最小值到最大值,每次check(mid)一遍,check的时候对于每个数组,用二进制的形式表示出来,数组中小于mid的值用0表示,大于等于mid的用1表示,此时所有的数组都进行了二进制转化,比如一个数组1 2 3 4 5,mid = 3,然后数组就可以状态压缩为0 0 1 1 1 。然后去枚举这些二进制,这样其实最多只会枚举2m × 2m 次,如果枚举的两组二进制相或为11111111,那么说明找到了一组解,返回继续二分,如此过程时间复杂度只有O(n×m + 2m×2m),m的范围只有8。具体看代码
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 3e5+;
int n,m;
int cnt[maxn];
int a[maxn][];
int num[];
int ans1,ans2;
bool check(int cur){
memset(num,,sizeof(num));//初始化num数组
for(int i = ;i<=n;i++){
int x = ;
for(int j = m - ;j>=;j--){
if(a[i][j]>=cur) x+=(<<j);///统计满足a[i][j]>=cur的数组的每一位
}
num[x] = i;//每个数组都转化为二进制
}
for(int i = ;i<(<<m);i++){
for(int j = ;j<(<<m);j++){
if(num[i]!= && num[j]!= && (j|i) == (<<m)-){//枚举二进制形式的所有数
ans1 = num[i];
ans2 = num[j];
return true;
}
}
}
return false;
}
int main(){
int r = -,l = 1e9+;
scanf("%d%d",&n,&m);
for(int i = ;i<=n;i++){
for(int j = ;j<m;j++){
scanf("%d",&a[i][j]);
r = max(r,a[i][j]);
l = min(l,a[i][j]);
}
}
int mid;
while(l<r){//二分答案
mid = (l+r+)/;
if(check(mid)) l = mid ;
else r = mid - ;
}
check(l);
printf("%d %d",ans1,ans2);
return ;
}
E. Messenger Simulator
题意:序列p的长度为n,初始序列为1 2 3 4 ...n,然后有m次操作,每次指定序列中一个数移动到第一位,然后剩下的所有序列往后移动一位,求每个数在出现过的所有历史序列中所在位置索引的最大值和最小值。
思路:用一个树状数组维护序列的位置,在序列的前面空出m个位置,目的是留给m次操作移动数字到前m个位置。初始时,在输入数据的时候,用pos数组记录所有数字的位置为 i+m,然后树状数组的 i+m处更新+1代表第i+m个位置放了一个数,每次移动操作时,在该位置做-1的更新操作表示此处清零,该位置已经没有放置数字,然后可以用树状数组查询该位置前面部分的区间和,就表示前面有多少个数,自然而然就可以更新这个数出现位置的最大值了,而最小值更新则为:如果进行了移动操作,那么该数字位置的最小值就是1了,因为把该数字放在了序列最前面,最后再遍历一遍所有数字,查询更新一些没有进行移动操作的数出现位置的最大值。具体看代码
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 3e5+;
int t[maxn*];
int ansMin[maxn+],ansMax[maxn+];
int n,m;
inline int lowbit(int x){
return x&(-x);
}
void add(int x,int k){
while(x<=n+m){
t[x] = t[x] + k;
x +=lowbit(x);
}
}
int get(int x){
int ans = ;
while(x>=){
ans+=t[x];
x-=lowbit(x);
}
return ans;
}
int main(){
scanf("%d%d",&n,&m);
int pos[n+m+];
for(int i = ;i<=n;i++){
pos[i] = i + m;//初始化元素的位置,pos[i]为元素i的位置
ansMin[i] = i,ansMax[i] = i;
add(i + m,);//树状数组该位置更新+1
}
for(int i = ;i<m;i++){
int temp;
scanf("%d",&temp);
ansMin[temp] = ;
add(pos[temp],-);//该位置-1,
add(m-i,);//移动到最前面,树状数组+1
ansMax[temp] = max(ansMax[temp],get(pos[temp]));//查询前面有多少个元素,做max的更新
pos[temp] = m - i;//更新位置
}
for(int i = ;i<=n;i++){
ansMax[i] = max(ansMax[i],get(pos[i]));//最后check没有进行移动操作的元素
}
for(int i = ;i<=n;i++){
printf("%d %d\n",ansMin[i],ansMax[i]);
}
return ;
}
b
)
Educational Codeforces Round 80 A-E简要题解的更多相关文章
- Codeforces Round #557 (Div. 1) 简要题解
Codeforces Round #557 (Div. 1) 简要题解 codeforces A. Hide and Seek 枚举起始位置\(a\),如果\(a\)未在序列中出现,则对答案有\(2\ ...
- Codeforces Round #545 (Div. 1) 简要题解
这里没有翻译 Codeforces Round #545 (Div. 1) T1 对于每行每列分别离散化,求出大于这个位置的数字的个数即可. # include <bits/stdc++.h&g ...
- Educational Codeforces Round 80 (Rated for Div. 2)部分题解
A. Deadline 题目链接 题目大意 给你\(n,d\)两个数,问是否存在\(x\)使得\(x+\frac{d}{x+1}\leq n\),其中\(\frac{d}{x+1}\)向上取整. 解题 ...
- Codeforces Round #483 (Div. 1) 简要题解
来自FallDream的博客,未经允许,请勿转载,谢谢. 为了证明一下我又来更新了,写一篇简要的题解吧. 这场比赛好像有点神奇,E题莫名是道原题,导致有很多选手直接过掉了(Claris 表演24s过题 ...
- Codeforces Round #498 (Div. 3) 简要题解
[比赛链接] https://codeforces.com/contest/1006 [题解] Problem A. Adjacent Replacements [算法] 将序列中的所有 ...
- Educational Codeforces Round 37-G.List Of Integers题解
一.题目 二.题目链接 http://codeforces.com/contest/920/problem/G 三.题意 给定一个$t$,表示有t次查询.每次查询给定一个$x$, $p$, $k$,需 ...
- Educational Codeforces Round 37-F.SUM and REPLACE题解
一.题目 二.题目链接 http://codeforces.com/contest/920/problem/F 三.题意 给定$N$个范围在$[1, 1e6)$的数字和$M$个操作.操作有两种类型: ...
- Codeforces Round #535(div 3) 简要题解
Problem A. Two distinct points [题解] 显然 , 当l1不等于r2时 , (l1 , r2)是一组解 否则 , (l1 , l2)是一组合法的解 时间复杂度 : O(1 ...
- Educational Codeforces Round 80 (Rated for Div. 2)
A. Deadline 题目链接:https://codeforces.com/contest/1288/problem/A 题意: 给你一个 N 和 D,问是否存在一个 X , 使得 $x+\lce ...
随机推荐
- Perl-统计文本中各个单词出现的次数(NVDIA2019笔试)
1.原题 2.perl脚本 print "================ Method 1=====================\n"; open IN,'<','an ...
- VMware Workstation Pro工具
安装包 链接:https://pan.baidu.com/s/1n-URb83lHtric3Ds8UbF9Q 提取码:c9z5 密钥 FF31K-AHZD1-H8ETZ-8WWEZ-WUUVA CV7 ...
- JN_0014:win10命令窗口以管理员方式启动
1,先打开命令窗口 2,固定到任务栏 3,右键任务栏图标 4,右键命令提示符, 5,选择以管理员方式启动.
- Python 变量&列表 初学者笔记
变量 消除空白后该变量需要存储一下(此操作常用于“储存用户输入并对其进行清理”) strip()消除两端空白 lstrip()消除前部空白 rstrip()消除末尾空白 upper()全部字母大写 ...
- mui下拉上拉(明一)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- 请写一个java类,在任何时候都可以向它查询“你已经创建了多少个对象?”
这个问题解决方法很简单,只要设置一个类的静态整型成员(事例中我设置的是n),初始化值为1,然后在其构造函数中添加语句使其+1(n++),这样需要查询创建了多少个对象时直接查询n的值就可以了,如下: p ...
- sqlserver中float转varchar时不显示科学计数法
MSSQL中 float转换为varchar 变成科学计数法解决方案 在系统初始化的时候,因为有同事,没有在数值型的数据前面加上 单引号,导致进入数据库后都变成float型我们需要做以下转换就能将 ...
- 解决ios手机中input输入框光标过长的问题
修改前css部分代码: .receiving-info .receiving-info-list input { display: inline-block; width: 70%; font-siz ...
- pandas玩转excel-> (1)如何利用pandas创建excel数据文件
#在Anaconda3 的Spyder中 #定义pandas模块为pd import pandas as pd #创建一个新的DataFrame对象,定义这个对象中有两个字段:ID和Name, ...
- dubbo的服务consumer与provider使用的api版本不一致,是否有影响
dubbo的服务consumer与provider使用的api版本不一致,是否有影响 最近新接手一个项目,看到定义的dubbo接口有些很奇葩的设定. 一.消费端 与 服务端 调用的接口中的数据包装类型 ...