牛客练习赛34 A(规律) B(暴力) C(思维) D(规律)

抽空写了一个比赛,这次的题目好像比之前(上半年)的简单许多??或许是因为有了新人过来,不想劝退吧(笑)

算了,这次的题就是找找规律,找找规律什么的,似乎没有什么其他的算法,所以显得比较简单??

在家写的,头文件什么的就随便敲敲了..

废话就不多说了,上代码

A-little w and Soda(规律)

题目链接:https://ac.nowcoder.com/acm/contest/297/A

题目大意:买汽水的那个情景了,不过数据范围变成了10^100罢了。

思路:先手写了四五个,突然发现...一个空瓶子就可以喝一瓶汽水(借一个然后还回去),然后是能买多少瓶水,就能再喝多少瓶水...注意,多余的那1元钱没有用,所以注意去掉就行了。

AC:

#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
#define ll long long
#define clean(a,b) memset(a,b,sizeof(a))

const int INF=0x3f3f3f3f;
const int MAXN=1e5+10;
const int mod=1e9+7;

char s[MAXN];
int main()
{
	int T;
	while(cin>>T)
	{
		while(T--)
		{
			clean(s,'\0');
			cin>>s;
			int l=strlen(s);
			if((s[l-1]-'0')%2)
				s[l-1]--;
			for(int i=0;i<l;++i)
				cout<<s[i];
			cout<<endl;
		}
	}
}

B-little w and Sum(暴力判断)

题目链接:https://ac.nowcoder.com/acm/contest/297/B

题目大意:中文题,自己看..

思路:因为题中明确指出一次只能修改一个数,因此我们完全可以便利一下,然后符合要求的ans++就行了

AC:

#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
#define ll long long
#define clean(a,b) memset(a,b,sizeof(a))

const int INF=0x3f3f3f3f;
const int MAXN=1e5+10;
const int mod=1e9+7;

int arr[MAXN];

int main()
{
	int n;
	while(cin>>n)
	{
		clean(arr,0);
		ll ans=0,res=0,sum=0;
		for(int i=1;i<=n;++i)
		{
			cin>>arr[i];
			sum+=arr[i];
		}
		for(int i=1;i<=n;++i)
		{
			if(sum-2*arr[i]==0)
				ans++;
		}
		if(ans)
			cout<<ans<<endl;
		else
			cout<<-1<<endl;
	}
}

C-little w and Segment Coverage(思维+原题变形)

题目链接:https://ac.nowcoder.com/acm/contest/297/C

题目大意:中文题,很容易读懂

思路:CF写过有一道类似的题:点此处见题 然后就是变形了,再搞一个数组记录一下区间点的多少,

AC:

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define clean(a,b) memset(a,b,sizeof(a))

const int INF=0x3f3f3f3f;
const int MAXN=1e5+10;
const int mod=1e9+7;

struct node{
	int l,r;
}line[MAXN];
ll sum[MAXN],res[MAXN];
int n,m;

int main()
{
	while(cin>>n>>m)
	{
		clean(line,0);
		clean(sum,0);
		clean(res,0);
		for(int i=1;i<=m;++i)
		{
			cin>>line[i].l>>line[i].r;
			sum[line[i].l]++;
			sum[line[i].r+1]--;
		}
		int last=0;
		for(int i=1;i<=n;++i)
		{
			sum[i]+=sum[i-1];//获取点被覆盖的次数 
			if(sum[i]==0)//多少个没有被覆盖的 
				last++;
		}
		for(int i=1;i<=n;++i)
		{
			if(sum[i]==1)//只覆盖了一次,消去的时候会消去 
				res[i]=res[i-1]+sum[i];
			else
				res[i]=res[i-1];
		}
//		for(int i=1;i<=n;++i)
//			cout<<sum[i]<<" ";
//		cout<<endl;
//		for(int i=1;i<=n;++i)
//			cout<<res[i]<<" ";
//		cout<<endl;
		int id,ans=INF;
		for(int i=1;i<=m;++i)
		{
			if(res[line[i].r]-res[line[i].l-1]<=ans)
				id=i,ans=res[line[i].r]-res[line[i].l-1];
		}
		cout<<id<<" "<<last+ans<<endl;
	}
}





D-little w and Exchange(规律)

题目链接:https://ac.nowcoder.com/acm/contest/297/D

题目大意:中文题,不翻译。

思路:观察发现,如果后面的那个数大于前面所有数之和+1的话,必定会出现找零的情况,否则就不会出现,判断一下就行了,然后加几个特判,比如只有一个数了,第一个数不是1了什么的。

AC:

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define clean(a,b) memset(a,b,sizeof(a))
 
const int INF=0x3f3f3f3f;
const int MAXN=1e5+10;
const int mod=1e9+7;
 
ll arr[MAXN];
ll n,m;
 
int main()
{
    while(cin>>n>>m)
    {
        clean(arr,0);
        for(int i=1;i<=n;++i)
            cin>>arr[i];
        sort(arr+1,arr+1+n);
        if(arr[1]!=1)
        {
            cout<<"NO"<<endl;
            continue;
        }
        int f=0;
        ll res=1;//可以组成res之前的任何数
        for(int i=2;i<=n;++i)
        {
            if(arr[i]<=res+1)
                res+=arr[i];
            else
            {
                f=0;
                break;
            }
            if(res>=m)
            {
                f=1;
                break;
            }
        }
        if(f||m<=res)
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40482358/article/details/85017559
今日推荐