Atcoder Beginner Contest 196

题目传送门

A.Difference Max

考试情况(正解)

日常水题
求出b-c即可

code
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a,b,c,d;
	cin>>a>>b>>c>>d;
	cout<<b-c;
	return 0;
}

B.Round Down

考试情况(正解)

数据范围过大,直接考虑字符串
将小数点以前的所有数字输出即可

code
#include<bits/stdc++.h>
using namespace std;
int main()
{
	string s;
	cin>>s;
	for(int i=0;i<s.size();i++)
	{
		if(s[i]=='.') return 0;
		cout<<s[i];
	}
	return 0;
}

C.Doubled

考试情况(正解)

无脑暴力即可

code
#include<bits/stdc++.h>
using namespace std;
int main()
{
	long long n;
	cin>>n;
	for(long long i=1;;i++)
	{
		
		if(i<=9)
		{
			if(i*10+i>n){
				cout<<i-1;
				return 0;
			}
		}
			
		else if(i<=99)
		{
			if(i*100+i>n){
				cout<<i-1;
				return 0;
			}
		}
			
		else if(i<=999)
		{
			if(i*1000+i>n){
				cout<<i-1;
				return 0;
			}
		}
			
		else if(i<=9999)
		{
			if(i*10000+i>n){
				cout<<i-1;
				return 0;
			}
		}
			
		else if(i<=99999)
		{
			if(i*100000+i>n){
				cout<<i-1;
				return 0;
			}
		}
			
		else if(i<=999999)
		{
			if(i*1000000+i>n){
				cout<<i-1;
				return 0;
			}
		}
		else if(i<=9999999)
		{
			if(i*10000000+i>n){
				cout<<i-1;
				return 0;
			}
		}
	}
	return 0;
}

D.Hanjo

考试情况

日常误以为是dp,看着像是一个棋盘类的状压dp,想不出来该怎么写,就放弃了

正解

实则只是一个垃(N)圾(B)的暴搜!
搜索每一种砖块放置情况,再不断回溯
因为题目所给的砖块一定能刚好铺满所有地板
所以只需要两格砖都有地方铺,一格砖也就一定能放下
具体细节见代码

code
#include<bits/stdc++.h>
using namespace std;
const int maxn=20;
int n,m,a,b,ans,vis[maxn][maxn];
void dfs(int x,int y,int s)
{
	if(!s)
	{
		ans++;
		return;
	}
	if(y==m+1)
	{
		dfs(x+1,1,s);//换行 
		return;
	}
	if(x==n+1) return;//出边界 
	dfs(x,y+1,s);//铺一格砖 
	if(!vis[x][y]&&x<n&&!vis[x+1][y])//竖铺两格砖 
	{
		vis[x][y]=vis[x+1][y]=1;
		dfs(x,y+1,s-1);
		vis[x][y]=vis[x+1][y]=0;//回溯 
	}
	if(!vis[x][y]&&y<m&&!vis[x][y+1])//横铺两格砖 
	{
		vis[x][y]=vis[x][y+1]=1;
		dfs(x,y+1,s-1);
		vis[x][y]=vis[x][y+1]=0;//回溯
	}
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&a,&b);
	dfs(1,1,a);
	printf("%d\n",ans);
	return 0;
}

E.Filters

考试情况

考试时码了这道题很久
最后还是会超时
写了一个n*q的算法,但还是T了8组

Wrong code
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int a[N],x[N],t[N];
int f[N],k=0,f1=0,f2=0;
int main()
{
	int n,q;
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&t[i]);
	scanf("%d",&q);
	for(int i=1;i<=q;i++) scanf("%d",&x[i]);
	for(int i=1;i<=n;i++) f[i]=1e9+1;
	for(int i=1;i<=q;i++)
	{
		int ans=x[i];
		f1=0;
		f2=0;
		k=0;
		for(int j=1;j<=n;j++)
		{
			if(t[j]==1) ans+=a[j];
			if(t[j]==2)
			{
				if(a[j]>=ans)
				{
					if(f1==0) k=j,f1=1;
					if(f[j]!=1e9+1)
					{
						f2=1;
						printf("%d\n",f[j]);
						break;
					}
					ans=a[j];
				}
			}
			if(t[j]==3)
			{
				if(a[j]<=ans)
				{
					if(f1==0) k=j,f1=1;
					if(f[j]!=1e9+1)
					{
						f2=1;
						printf("%d\n",f[j]);
						break;
					}
					ans=a[j];
				}
			}
		}
		if(f2==1) continue;
		printf("%d\n",ans);
		if(f1==1) f[k]=ans;
	}
	return 0;
}
正解

看了许多正解,都是拿我不会的线段树来写的裂开
但是!
我看到了一个和我想法接近的代码,就是预处理出一个表达式
使每次输入都可以直接用这个表达式计算结果
即找到最终结果需要被比较的最大值和最小值,再加上所有被加的数字
所以
代码如下

code
#include<bits/stdc++.h>
using namespace std;
int n,q;
long long maxn=-1e16,minn=1e16,P;
int main()
{
	cin>>n;
	while(n--)
	{
		int a,t;
		cin>>a>>t;
		if(t==1) P+=a;
		else if(t==3) minn=min(minn,a-P),maxn=min(maxn,a-P);
		else maxn=max(maxn,a-P),minn=max(minn,a-P);
	}
	cin>>q;
	while(q--)
	{
		long long x;
		cin>>x;
		cout<<max(min(x,R),L)+P<<endl;
	}
}

总结

1.还是不要多想dp了,老老实实想想贪心与暴搜

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值