2020牛客多校第八场于2020/8/3

今天是第一次品尝到了差一点点就能过题的悲哀
主要是榜单被带歪了,真正的签到题G开题太晚了,加上我对字符输入的不熟悉,把两个循环都写出了低级错误,最后在比赛结束五分钟时才检查出来,遗憾至极。

G

模拟
由于题意稍微稍微有点难理解,榜单有点歪
看不懂题意的先去搜索一下set牌的规则

#include<bits/stdc++.h>
using namespace std;
struct node
{
	int a,b,c,d;	
}nod[305];
bool hanshu(int j,int k,int q)
{
	if(nod[j].a!=4&&nod[k].a!=4&&nod[q].a!=4)
	{
		if(nod[j].a==nod[k].a&&nod[k].a!=nod[q].a)return 0;
		if(nod[j].a==nod[q].a&&nod[j].a!=nod[k].a)return 0;
		if(nod[k].a==nod[q].a&&nod[j].a!=nod[k].a)return 0;
	}
	if(nod[j].b!=4&&nod[k].b!=4&&nod[q].b!=4)
	{
		if(nod[j].b==nod[k].b&&nod[k].b!=nod[q].b)return 0;
		if(nod[j].b==nod[q].b&&nod[j].b!=nod[k].b)return 0;
		if(nod[k].b==nod[q].b&&nod[j].b!=nod[k].b)return 0;
	}
	if(nod[j].c!=4&&nod[k].c!=4&&nod[q].c!=4)
	{
		if(nod[j].c==nod[k].c&&nod[k].c!=nod[q].c)return 0;
		if(nod[j].c==nod[q].c&&nod[j].c!=nod[k].c)return 0;
		if(nod[k].c==nod[q].c&&nod[j].c!=nod[k].c)return 0;
	}
	if(nod[j].d!=4&&nod[k].d!=4&&nod[q].d!=4)
	{
		if(nod[j].d==nod[k].d&&nod[k].d!=nod[q].d)return 0;
		if(nod[j].d==nod[q].d&&nod[j].d!=nod[k].d)return 0;
		if(nod[k].d==nod[q].d&&nod[j].d!=nod[k].d)return 0;
	}
	return 1;
}
int main()
{
	int t;
	cin>>t;
	for(int i=1;i<=t;i++)
	{
		string s;
		int n;
		cin>>n;
		for(int j=1;j<=n;j++)
		{
			cin>>s;
			int cnt=0;
			for(int k=1;k<s.length();k++)
			{
				
				if(s[k-1]=='[')
				{
					cnt++;
					
					if(cnt==1)
					{
						
						if(s[k]=='o')nod[j].a=1;
						else if(s[k+1]=='w')nod[j].a=2;
						else if(s[k+1]=='h')nod[j].a=3;
						else nod[j].a=4;
					//	cout<<nod[j].a<<endl;
					}
					if(cnt==2)
					{
						
						if(s[k]=='*')nod[j].b=4;
						else if(s[k]=='d')nod[j].b=1;
						else if(s[k]=='s')nod[j].b=2;
						else nod[j].b=3;
					//	cout<<nod[j].b<<endl;
					}
					if(cnt==3)
					{
						
						if(s[k]=='*')nod[j].c=4;
						else if(s[k]=='o')nod[j].c=3;
						else if(s[k+1]=='o')nod[j].c=1;
						else nod[j].c=2;
					//	cout<<nod[j].c<<endl;
					}
					if(cnt==4)
					{
						if(s[k]=='*')nod[j].d=4;
						else if(s[k]=='r')nod[j].d=1;
						else if(s[k]=='g')nod[j].d=2;
						else nod[j].d=3;
					//	cout<<nod[j].d<<endl;
					}
					
				}
				
			}
			//cout<<cnt<<endl;
																	
		}
		bool leap=0;
		
		for(int j=1;j<=n;j++)
		{
			if(leap==1)break;
			for(int k=j+1;k<=n;k++)
			{
				if(leap==1)break;
				for(int q=k+1;q<=n;q++)
				{
					if(hanshu(j,k,q)==1)
					{
						leap=1;
						cout<<"Case #"<<i<<": "<<j<<" "<<k<<" "<<q<<endl;
						break;
					}
				}
			}
		}
		
		if(leap==0)cout<<"Case #"<<i<<": -1"<<endl;
	}
}

K

想到了是用前缀和与优先队列(但是放给我写我估计写不来),但是数据范围超过了long long,虽然我刚学了高精度算法,但是板子是不带负数的,队友改板子+搜板子整整三个小时以上…辛苦辛苦,佩服佩服
然而!出题人轻易地说用两个long long做?我就仔细研究了一下类似代码。
得出结论:人家才是真的把高精度用活了啊啊啊啊啊!两个long long模拟高精度,膜拜。
贴上代码(我方):

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
ll a[maxn],b[maxn],pre[maxn],tot[maxn];
priority_queue<ll> q;
#define MAXN 999999999
#define MAXSIZE 5000
#define DLEN 9
class BigInt
{
    private:
        int a[500];
        int len;
        bool sign;
        //sign表示符号位的正负~
    protected:
        BigInt add(const BigInt&,const bool)const;
        BigInt subtract(const BigInt&,const bool)const;
         //两个无符号整形的加减法,flag标明结果的符号位~~
    public:
        BigInt() {sign=false;len=1;memset(a,0,sizeof(a));}
        BigInt(const ll);
        BigInt(const char*);
        BigInt(const BigInt&);
        BigInt& operator=(const BigInt&);
        friend istream& operator>>(istream&,BigInt&);
        friend ostream& operator<<(ostream&,const BigInt&);
        friend BigInt abs(const BigInt&);
   
        BigInt operator+(const BigInt&)const;
        BigInt operator-(const BigInt&)const;
        BigInt operator*(const BigInt&)const;
        BigInt operator/(const BigInt&)const;
        BigInt operator/(const int&)const;
   
        BigInt operator^(const int&)const;
        int operator%(const int&)const;
        bool operator<(const BigInt&)const;
        bool operator>(const BigInt&)const;
        bool operator<=(const BigInt&)const;
        bool operator>=(const BigInt&)const;
        bool operator==(const BigInt&)const;
   
        inline int size() {return DLEN*(len-1)+to_string(a[len-1]).size();}
};
//对于负数的处理~~~
BigInt::BigInt(ll b)
{
    ll c,d=abs(b);
    len=0;
    sign=b<0;
    memset(a,0,sizeof(a));
    while(d>MAXN)
    {
        c=d-(d/(MAXN+1))*(MAXN+1);
        d=d/(MAXN+1);
        a[len++]=c;
    }
    a[len++]=d;
}
BigInt::BigInt(const char *in)
{
    const char *s;
    if(in[0]=='-') s=in+1,sign=true;
    else s=in,sign=false;
    int t,k,index,L,i;
    memset(a,0,sizeof(a));
    L=strlen(s);
    len=L/DLEN;
    if(L%DLEN) len++;
    index=0;
    for(i=L-1;i>=0;i-=DLEN)
    {
        t=0;
        k=i-DLEN+1;
        if(k<0) k=0;
        for(int j=k;j<=i;j++)
            t=t*10+s[j]-'0';
        a[index++]=t;
    }
}
BigInt::BigInt(const BigInt& T):len(T.len),sign(T.sign)
{
    memset(a,0,sizeof(a));
    for(int i=0;i<len;i++)
        a[i]=T.a[i];
}
BigInt& BigInt::operator=(const BigInt& n)
{
    sign=n.sign;
    len=n.len;
    memset(a,0,sizeof(a));
    for(int i=0;i<len;i++)
        a[i]=n.a[i];
    return *this;
}
//MDZZ~不是和字符串转化为BigInt一样么,233333
istream& operator>>(istream& in,BigInt& b)
{
    char ch[MAXSIZE];
    in>>ch;
    b=BigInt(ch);
    return in;
}
ostream& operator<<(ostream& out,const BigInt& b)
{
    out<<(b.sign?"-":"")<<b.a[b.len-1];
    for(int i=b.len-2;i>=0;i--) out<<setw(DLEN)<<setfill('0')<<b.a[i];
    return out;
}
BigInt abs(const BigInt& T)
{
    BigInt t(T);
    t.sign=false;
    return t;
}
BigInt BigInt::add(const BigInt& T,const bool flag)const
{
    BigInt t(*this);
    t.sign=flag;
    int big;
    big=T.len>len?T.len:len;
    for(int i=0;i<big;i++)
    {
        t.a[i]+=T.a[i];
        if(t.a[i]>MAXN)
        {
            t.a[i+1]++;
            t.a[i]-=MAXN+1;
        }
    }
    if(t.a[big]!=0) t.len=big+1;
    else t.len=big;
    return t;
}
BigInt BigInt::subtract(const BigInt& T,const bool flag)const
{
    BigInt t(*this);
    t.sign=flag;
    for(int i=0;i<t.len;i++)
    {
        if(t.a[i]<T.a[i])
        {
            //模拟借位运算过程~
            int j=i+1;
            while(t.a[j]==0) j++;
            t.a[j--]--;
            while(j>i) t.a[j--]+=MAXN;
            t.a[i]+=MAXN+1-T.a[i];
        }
        else t.a[i]-=T.a[i];
    }
    while(t.a[t.len-1]==0&&t.len>1) t.len--;
    return t;
}
BigInt BigInt::operator+(const BigInt& T)const
{
    BigInt ret;
    if(sign && T.sign){
        BigInt t1(*this),t2(T);
        ret=t1.add(t2,false);
        ret.sign=true;
    }
    if(sign^T.sign)
    {
        BigInt t1(*this),t2(T);
        if(abs(t1)<abs(t2)) swap(t1,t2);
        ret=t1.subtract(t2,t1.sign);
        if(ret.a[ret.len-1]==0&&ret.len==1) ret.sign=false;
    }
    else ret=this->add(T,sign);
    return ret;
}
BigInt BigInt::operator-(const BigInt& T)const
{
    BigInt ret;
    if(sign^T.sign) ret=this->add(T,sign);
    else
    {
        BigInt t1(*this),t2(T);
        bool sn;
        if(abs(t1)<abs(t2))
        {
            sn=t1.sign^1;
            swap(t1,t2);
        }
        else sn=t1.sign;
        ret=t1.subtract(t2,sn);
        if(ret.a[ret.len-1]==0&&ret.len==1) ret.sign=false;
    }
    return ret;
}
BigInt BigInt::operator*(const BigInt& T)const
{
    BigInt ret;
    long long up;
    long long temp,temp1;
    for(int i=0;i<len;i++)
    {
        up=0;
        for(int j=0;j<T.len;j++)
        {
            temp=(long long)a[i]*T.a[j]+ret.a[i+j]+up;
            if(temp>MAXN)
            {
                temp1=temp%(MAXN+1);
                up=temp/(MAXN+1);
                ret.a[i+j]=temp1;
            }
            else
            {
                up=0;
                ret.a[i+j]=temp;
            }
        }
        if(up!=0) ret.a[i+T.len]=up;
    }
    ret.sign=sign^T.sign;
    ret.len=len+T.len;
    while(ret.a[ret.len-1]==0&&ret.len>1) ret.len--;
    return ret;
}
BigInt BigInt::operator/(const BigInt& T)const
{
    BigInt r(*this),ret((ll)0);
    while(r>=T)
    {
        BigInt down(1);
        while(r-T*down>=(ll)0) down=down*10;
        down=down/10;
        r=r-T*down;
        ret=ret+down;
    }
    ret.sign=sign^T.sign;
    return ret;
}
BigInt BigInt::operator/(const int &b)const
{
    BigInt ret;
    bool sign1=b<0;
    long long down=0;
    for(int i=len-1;i>=0;i--)
    {
        ret.a[i]=(a[i]+down*(MAXN+1))/b;
        down=a[i]+down*(MAXN+1)-(long long)ret.a[i]*b;
    }
    ret.sign=sign^sign1;
    ret.len=len;
    while(ret.a[ret.len-1]==0&&ret.len>1) ret.len--;
    return ret;
}
int BigInt::operator%(const int &b)const
{
    int d=0;
    for(int i=len-1;i>=0;i--)
        d=(((long long)d*(MAXN+1))%b+a[i])%b;
    return sign?-d:d;
}
BigInt BigInt::operator^(const int &n)const
{
    BigInt ret(1),t(*this);
    int m=n;
    while(m)
    {
        if(m&1) ret=ret*t;
        t=t*t;
        m>>=1;
    }
    return ret;
}
bool BigInt::operator<(const BigInt& T)const
{
    if(sign&&!T.sign) return true;
    if(!sign&&T.sign) return false;
    //只有sign相同才能作比较~~
    if(len!=T.len) return sign^(len<T.len);
    for(int ln=len-1;ln>=0;ln--)
        if(a[ln]!=T.a[ln]) return sign^(a[ln]<T.a[ln]);
    return false;
}
bool BigInt::operator>(const BigInt& T)const
{
    return T<*this;
}
bool BigInt::operator<=(const BigInt& T)const
{
    if(*this==T) return true;
    return *this<T;
}
bool BigInt::operator>=(const BigInt& T)const
{
    return T<=*this;
}
bool BigInt::operator==(const BigInt& T)const
{
    if(sign!=T.sign||len!=T.len) return false;
    for(int i=len-1;i>=0;i--)
        if(a[i]!=T.a[i]) return false;
    return true;
}
  
int main()
{
    int T;scanf("%d",&T);
    int casenum=1;
    while(casenum<=T)
    {
        int num;scanf("%d",&num);
        pre[0]=0;
        for(int i=1;i<=num;++i)
            scanf("%lld",&a[i]),pre[i]=pre[i-1]+a[i];
        tot[0]=0x3f3f3f3f;
        for(int i=1;i<=num;++i)
            scanf("%lld",&b[i]),tot[i]=min(b[i],tot[i-1]);
        ll ans=0;while(!q.empty()) q.pop();
        int pnum=b[1];
        BigInt a((ll)0);
        for(int i=1;i<=num;++i)
        {
            while(pnum>tot[i]){
                BigInt c(q.top());
                 
                a=a+c;
                pnum--;
            }
            q.push(pre[i]);
        }
        while(pnum>0){
                BigInt c(q.top());
                a=a+c;
                pnum--;
        }
        printf("Case #%d: %lld ",casenum++,b[1]);
        cout<<a<<endl;
    }
}

大佬方代码:

#include<bits/stdc++.h>
using namespace std;
const long long N=1e5+9,mod=1e14;
long long a[N],b[N],s[N],n,m,ans;
int main()
{
    int T,t,l,r,i,j,k;
    scanf("%d",&T);
    for(k=1;k<=T;k++)
    {
        memset(a,0,sizeof(a)),memset(b,0,sizeof(b)),memset(s,0,sizeof(s));
        scanf("%lld",&n);
        for(i=0;i<n;i++) scanf("%lld",&a[i]);
        scanf("%lld",&b[0]);
        for(i=1;i<n;i++) scanf("%lld",&b[i]),b[i]=min(b[i],b[i-1]);
        s[0]=a[0];
        for(i=1;i<n;i++) s[i]=s[i-1]+a[i];
        l=r=t=ans=0,m=s[l]*b[l];
        while(r<n)
        {
            while(r<n && s[r]<=s[l]) r++;
            if(r==n)break;
            m+=b[r]*(s[r]-s[l]),ans+=m/mod,m%=mod;
            l=r,t=0;
        }
        printf("Case #%d: %lld ",k,b[0]);
        if(ans) printf("%lld%014lld\n",ans,m);
        else printf("%lld\n",m);
    }
}

I

该题稍后再补。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值