小言_互联网的博客

Codeforces Round #637 (Div. 2)题解+总结

287人阅读  评论(0)

题目链接

A - Nastya and Rice

题目大意:每个物品质量范围在 a b a-b $a+b$内,你需要判断n个物品总质量范围在不在$c-d$ c + d c+d 内。

题解:其实就是判断两个区间是否相交,分三种情况讨论即可。(我做的时候一直少考虑一种情况,白给了三发)

代码

#include <bits/stdc++.h>
 
using namespace std;
 
#define mem(a, x) memset(a, x, sizeof(a))
#define IOS std::ios::sync_with_stdio(false)
#define ls o<<1
#define rs o<<1|1
#define test(a) cout<<a<<endl;
#define exp 0.000001
#define pb push_back
typedef long long ll;
const int mod = 1e9+7;
const int maxn = 2e5 + 5;
const int inf = 0x3f3f3f3f;
 
 
 
void solve()
{
int n;
scanf("%d",&n);
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
int temp1=(a-b)*n;
int temp2=(a+b)*n;
if((temp1>=c-d&&temp1<=c+d)||(temp2>=c-d&&temp2<=c+d)||(temp1<=c-d&&temp2>=c+d)){
printf("Yes\n");
return ;
}
printf("No\n");
}
int main()
{
    int t;scanf("%d",&t);while(t--)
    solve();
	return 0;
}

B - Nastya and Door

题目大意:给你一个数组,当 a i > = a i 1 a_i>=a_{i-1} a i > = a i + 1 a_i>=a_{i+1} 时,称 a i a_i 为数组的峰,让你求长度为k的连续段中的峰的最大值(首尾不算峰)。

题解:先预处理出所有峰,然后从左向右依次遍历。时间复杂度O(n)。

代码

#include <bits/stdc++.h>
 
using namespace std;
 
#define mem(a, x) memset(a, x, sizeof(a))
#define IOS std::ios::sync_with_stdio(false)
#define ls o<<1
#define rs o<<1|1
#define test(a) cout<<a<<endl;
#define exp 0.000001
#define pb push_back
typedef long long ll;
const int mod = 1e9+7;
const int maxn = 2e5 + 5;
const int inf = 0x3f3f3f3f;
 
 
int a[maxn];
int vis[maxn];
void solve()
{
int k,n;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
vis[i]=0;
}
for(int i=2;i<n;i++)
if(a[i]>a[i-1]&&a[i]>a[i+1])
	vis[i]=1;
int l=1,p=0;
for(int i=1;i<k;i++)
{
if(vis[i])
	p++;
}
int ll=1,rr=k;
int temp=p;
while(rr<n)
{
if(vis[ll+1])
	temp--;
if(vis[rr])
	temp++;
ll++;
rr++;
if(temp>p)
{
	p=temp;
	l=ll;
}
}
p++;
printf("%d %d\n",p,l);
}
int main()
{
    int t;scanf("%d",&t);while(t--)
    solve();
	return 0;
}

C. Nastya and Strange Generator

题目大意:题目定了两个数列, r i r_i 表示从 i i ~ n n 第一个还没被放置的数字。 c o u n t i count_i 表示数列 r r i i 的个数。并规定每一次只能放置count中最大所对应的下标。给你一种放置方案问你是否符合。

题解:很明显刚开始 c o u n t count 数列全为 1 1 ,如果我们放置最后一个数字,则依然全为 1 1 。如果我们放置之前的任一数字,我们就不得不从这个数字开始按顺序放到最大。按照上述放置方法模拟就好。

代码

#include <bits/stdc++.h>
 
using namespace std;
 
#define mem(a, x) memset(a, x, sizeof(a))
#define IOS std::ios::sync_with_stdio(false)
#define ls o<<1
#define rs o<<1|1
#define test(a) cout<<a<<endl;
#define exp 0.000001
#define pb push_back
typedef long long ll;
const int mod = 1e9+7;
const int maxn = 2e5 + 5;
const int inf = 0x3f3f3f3f;
 
 
int a[maxn];
void solve()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
	scanf("%d",&a[i]);
}
int cnt=1;
int temp=n;
while(cnt<=n)
{
if(a[cnt]==temp)
{
	temp--;
	cnt++;
}
else {
	int i;
for(i=cnt+1;;i++)
{
	
	if(a[i]!=a[i-1]+1)
	{
		printf("NO\n");
		//test(i);
		return ;
	}
	if(a[i]==temp)
		break;
}
temp=a[cnt]-1;
cnt=i+1;
}
}
printf("YES\n");
}
int main()
{
    int t;scanf("%d",&t);while(t--)
    solve();
	return 0;
}

D - Nastya and Scoreboard

题目大意:有 n n 个计分数字从左到右显示数字,每个数字有 7 7 个二极管,但是这些二极管有k个不亮了。他问你原本计分板上的数字最大可能是多少。

题解:题目可以等价于点亮 k k 个二极管所能现实的最大数字。先预处理出每一位补全到各个数字需要点亮的二极管的数目,如果不行置为 1 -1 。题目的难点就在于要正好点亮 k k 个二极管(不能多也不能少)。我们只需要对所需的二极管数目求一个后缀和并压入到一个集合中去重(超过 k k 直接舍去),从左到右并对于每一位从大到小进行枚举。

代码

#include <bits/stdc++.h>
 
using namespace std;
 
#define mem(a, x) memset(a, x, sizeof(a))
#define IOS std::ios::sync_with_stdio(false)
#define ls o<<1
#define rs o<<1|1
#define test(a) cout<<a<<endl;
#define exp 0.000001
#define pb push_back
typedef long long ll;
const int mod = 1e9+7;
const int maxn = 2e5 + 5;
const int inf = 0x3f3f3f3f;
 
 
string s[2005];
string ck[10]={"1110111","0010010","1011101","1011011","0111010","1101011","1101111","1010010","1111111","1111011"};
set<int> si[2005];
int vi[2005][10];
int ans[2005];
void solve()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
	cin>>s[i];
mem(vi,-1);
for(int i=1;i<=n;i++)
   si[i].clear();
si[n+1].insert(0);
for(int i=n;i>=1;i--)
{
	 for(int j=0;j<=9;j++)
	 {
	 	int cnt=0,flag=1;
	 	for(int k=0;k<=6;k++)
	 	{
	 		if(s[i][k]=='1'&&ck[j][k]=='0')
	 		{
	 			flag=0;
	 			break;
	 		}
	 		else if(s[i][k]=='0'&&ck[j][k]=='1')
	 			cnt++;
	 	}
	 	if(flag)
        vi[i][j]=cnt;
	 }
	 for(int j=0;j<=9;j++)
	 {
	 	if(vi[i][j]!=-1)
	 	{   
	 		 set<int>::iterator it;
	 		 for(it=si[i+1].begin();it!=si[i+1].end();it++)
	 		 {
	 		 	if(*it+vi[i][j]<=k)
	 		 	si[i].insert(*it+vi[i][j]);
	 		 }
	 	}
	 }
}
for(int i=1;i<=n;i++)
{
	int j;
	for(j=9;j>=0;j--)
	{
		if(vi[i][j]!=-1&&si[i+1].count(k-vi[i][j]))
		{
			ans[i]=j+'0';
			k-=vi[i][j];
			break;
		}
	}
	if(j==-1)
	{
		printf("-1\n");
		return ;
	}
}
for(int i=1;i<=n;i++){
if(i==n)
printf("%c\n",ans[i]);
else printf("%c",ans[i]);
}
}
int main()
{
    //int t;scanf("%d",&t);while(t--)
    solve();
	return 0;
}

转载:https://blog.csdn.net/m0_46527476/article/details/105724879
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场