Educational Codeforces Round 82 (Rated for Div. 2)(A~D)

唉,有点可惜,感觉D题能做出来,可惜时间有点不够了…果然教育场被教育…
先写三个题的题解吧,剩下的慢慢补。

A. Erasing Zeroes

A就没什么好说的了,统计出最左和最右的位置看一下中间有多少0就行。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100010,mod=1e9+7;
int main()
{
	int t;  cin>>t;
	while(t--)
	{
		string s;   cin>>s;
		int res=0,l=-1,r=0,num=0;
		for(int i=0;i<s.size();i++)
		{
			if(s[i]=='1')
			{
			  num++;
			  if(l==-1) l=i;
			  r=i;
			}
		}
		if(num==0) 
            cout<<0<<endl;
		else
			cout<<r-l+1-num<<endl;
	}	
	return 0;
}

B. National Project

B是真的有那点坑,题面说的是修完整条路…修完整条路…思路直接看代码吧!还是比较简单的.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
	ll t; cin>>t;
	while(t--)
    {
		ll n,g,b;   cin>>n>>g>>b;
		ll tmp=(n+1)/2;
		if(tmp<=g)  //所需高质量比g小直接输出n就行
			cout<<n<<endl;
		else
		{
			ll num=tmp/g;
			ll ans;
			if(tmp%g==0)  等于0说明是有num-1个整周全再加g天
				ans=(num-1)*(g+b)+g;
			else
				ans=(num)*(g+b)+tmp%g; 不等于0说明有num个周期再加剩余的几天
			cout<<max(ans,n)<<endl;
		}
	}
	return 0;
}

C. Perfect Keyboard

其实蒟蒻想到的是双向链表,但是忘了,2333,只能写成数组了。。。
手动模拟一下这个题就会发现有个规律,他每次都是在某个数的左右移动才行。
就像这个样例:zxzytyz。z先放,然后x!=z,所以x放在z右边,再看下一个z,因为等于当前位置-1的那个字母,所以直接让当前位置-1,而不需要的添加新的位置,以此类推,(假设当前位置为ans),每次判断ans,ans-1,ans+1;相等的话就让当前位置++,–,或不变。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
char str[205],ans[105];
bool vis[105];

int main()
{
	int T;  scanf("%d",&T);
	while (T--)
	{
		scanf("%s",str+1);
		int n=strlen(str+1),l=27,r=27,now=27,flag=0;
		ans[l]=str[1];
		memset(vis,0,sizeof(vis));
		vis[str[1]-'a']=1;
		for (int i=2;i<=n;i++)
		{
			if (now>l&&ans[now-1]==str[i])
                now--;
			else if (now<r&&ans[now+1]==str[i])
                now++;
			else if (now==l&&!vis[str[i]-'a'])
                ans[--l]=str[i],now--,vis[str[i]-'a']=1;
			else if (now==r&&!vis[str[i]-'a'])
                ans[++r]=str[i],now++,vis[str[i]-'a']=1;
			else
			{
			    flag=1;
                break;
            }
		}
		if (flag)
            puts("NO");
		else
		{
			puts("YES");
			for (int i=l;i<=r;i++)
                putchar(ans[i]);
			for (int i=0;i<26;i++)
				if (!vis[i]) putchar(i+'a');
			puts("");
		}
	}
	return 0;
}

上面是大佬的代码,如果不理解可以看一下蒟蒻的代码,真的是不好意思放出来…

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int N = 2e5+5;
int a[600];
int b[60];

int main()
{
	ll t;cin>>t;
	while(t--)
    {
        memset(a,-1,sizeof a);
        memset(b,-1,sizeof b);
        string s;cin>>s;
        a[300]=s[0]-'a';
        int x=300;
        int flag=1;
        for(int i=1;i<s.size();i++)   //直接处理字符串然后存入一个数组中
        {
            if((s[i]-'a')!=a[x-1]&&(s[i]-'a')!=a[x+1]&&(s[i]-'a')!=a[x])
            {
                if(a[x+1]!=-1&&a[x-1]!=-1)
                {
                    flag=0;
                    break;
                }
                if(a[x+1]==-1)
                {
                    x++;
                    a[x]=s[i]-'a';
                }
                if(a[x-1]==-1)
                {
                    x--;
                    a[x]=s[i]-'a';
                }

            }
            else if((s[i]-'a')==a[x-1])
                x--;
            else if((s[i]-'a')==a[x+1])
                x++;
        }
        if(!flag)
            cout<<"NO"<<endl;
        else
        {
            set<int> st;
            for(int i=0;i<600;i++)    //判断是不是有重复元素
            {
                if(a[i]!=-1)
                {
                    if(st.count(a[i]))
                        flag=0;
                    else
                        st.insert(a[i]);
                }
            }
            if(!flag)
                cout<<"NO"<<endl;
            else
            {
                cout<<"YES"<<endl;
                for(int i=0;i<600;i++)//没有的话顺序输出数组里面的东西,然后再将剩下的输出
                {
                    if(a[i]!=-1)
                    {
                       cout<<char(a[i]+'a');
                       b[a[i]]=1;

                    }
                }
                for(int i=0;i<26;i++)
                    if(b[i]==-1)
                        cout<<char(i+'a');
                cout<<endl;
            }
        }

    }

	return 0;
}

D. Fill The Bag

妈耶,真的是第一印象二进制一直往二进制那方面想…虽然也能写出来但是真的是不如贪心来的舒服,直接看代码吧,思路一眼就能看出来.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int main()
{
	int t;cin>>t;
	while (t--)
    {
        ll s,n,m,x,ans;
		cin>>n>>m;
		s=ans=0;
		multiset<ll,greater<ll>> f;
		while (m--)
        {
            cin>>x;
            s+=x;
            f.insert(x);
        }
		if (s<n)//和都小于n了,还分解啥呀...
            cout<<"-1"<<endl;
		else
		{
			while(n)
			{
				m=*f.begin();
				f.erase(f.begin());
				if(m<=n)  //m<=n不用分解,直接减去
				{
				    n-=m;
				    s-=m;
				}
				else if(s-m<n)  //除了m剩下的<n,把m拆开俩半防防止后边不够
                {
                    ans++;
                    f.insert(m/2);
                    f.insert(m/2);
                }
				else  //剩下的m>n&&s-m>n,这种情况要不要m都无所谓
                    s-=m;
			}
			cout<<ans<<endl;
		}
	}
}

E感觉能DP出来,待补吧…FG就算了,还是继续保命…

E. Erase Subsequences

能出来个鬼,写了一中午不是最后一个大大的WA,差点我自己就信了…

发布了41 篇原创文章 · 获赞 5 · 访问量 2222

猜你喜欢

转载自blog.csdn.net/mumuhaoshuai/article/details/104290856