【纪中2020.4.18日】模拟赛题解

目录:

T1:Mixing Milk
T2:The Bucket List
T3:Back and Forth

又双叒叕是USACO 我要吐了……

正题:

T1:Mixing Milk

题目描述

农业,尤其是生产牛奶,是一个竞争激烈的行业。Farmer John发现如果他不在牛奶生产工艺上有所创新,他的乳制品生意可能就会受到重创!
幸运的是,Farmer John想出了一个好主意。他的三头获奖的乳牛,Bessie、Elsie和Mildred,各自产奶的口味有些许不同,他打算混合这三种牛奶调制出完美的口味。
为了混合这三种不同的牛奶,他拿来三个桶,其中分别装有三头奶牛所产的奶。这些桶可能有不同的容积,也可能并没有完全装满。然后他将桶1的牛奶倒入桶2,然后将桶2中的牛奶倒入桶3,然后将桶3中的牛奶倒入桶1,然后再将桶1的牛奶倒入桶2,如此周期性地操作,共计进行100次(所以第100次操作会是桶1倒入桶2)。当Farmer John将桶a中的牛奶倒入桶b时,他会倒出尽可能多的牛奶,直到桶a被倒空或是桶b被倒满。
请告诉Farmer John当他倒了100次之后每个桶里将会有多少牛奶。

输入

输入文件的第一行包含两个空格分隔的整数:第一个桶的容积c1,以及第一个桶里的牛奶量m1。c1和m1均为正,并且不超过10^9。第二和第三行类似地包含第二和第三个桶的容积和牛奶量。

输出

输出三行,给出倒了100次之后每个桶里的牛奶量。

样例输入

10 3
11 4
12 5

样例输出

0
10
2

分析:

此题为模拟
题意为三个桶,所以为四种情况
用一个量表示当前桶,分别模拟就行

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring> 
using namespace std;
int a[5],b[5],turn=1;  //turn为当前桶
int main()
{
	freopen("mixmilk.in","r",stdin);
	freopen("mixmilk.out","w",stdout);
    cin>>a[1]>>b[1]>>a[2]>>b[2]>>a[3]>>b[3];
    for(int i=1;i<=4;i++){
        if(turn==4) turn=1;  //4就是新的一个循环
        if(turn==1||turn==2){
            int ans=b[turn]+b[turn+1];  //当前
            if(ans>=a[turn+1]) {
                b[turn]=ans-a[turn+1];
                b[turn+1]=a[turn+1];  //替换
            }
            else{
                b[turn+1]=ans;  //重新赋值
                b[turn]=0;
            }
        }
        if(turn==3){  
            int ans=b[turn]+b[1];  
            if(ans>=a[1]){
                b[turn]=ans-a[1];
                b[1]=a[1];
            }
            else{
                b[1]=ans;
                b[turn]=0;  //重新赋值
            }
        }
        turn++;  //下一轮
    }
    cout<<b[1]<<endl<<b[2]<<endl<<b[3];
    return 0;
}

T2:The Bucket List

题目描述

Farmer John正在考虑改变他给奶牛挤奶的时候分配牛奶桶的方式。他认为这最终能使得他使用数量更少的桶,然而他不清楚具体是多少。请帮助他!
Farmer John有N头奶牛(1≤N≤100),方便起见编号为1…N。第i头奶牛需要从时间si到时间ti之间挤奶,并且挤奶过程中需要用到bi个桶。于是多头奶牛可能在同一时刻都在挤奶;如果这样,她们不能使用相同的桶。也就是说,一个在第i头奶牛挤奶时用的桶不可以被任何在时间si到时间ti之间挤奶的其他奶牛使用。当然,这个桶在这段时间之外可以被其他奶牛所使用。为了简化他的工作,FJ保证在任一时刻,至多只有一头奶牛开始或是结束挤奶(也就是说,所有的si和ti各不相同)。
FJ有一个储藏室,里面有依次编号为1、2、3、……的桶。在他的挤奶策略中,当某一头奶牛(比如说,奶牛i)开始挤奶(在时间si),FJ就跑到储藏室取出编号最小的bi个桶分配给第i头奶牛用来挤奶。
请求出FJ需要在储藏室中存放多少个桶才能使得他能够顺利地给所有奶牛挤奶。

输入

输入的第一行包含N。以下N行,每行描述了一头奶牛,包含三个空格分隔的数si,ti,和bi。其中si和ti均为1…1000之间的整数,bi为1…10之间的整数。

输出

输出一个整数,为FJ需要的桶的数量。

样例输入

3
4 10 1
8 13 3
2 6 2

样例输出

4

分析:

区间覆盖的问题
直接暴力即可,空间时间限制基本没有似的

CODE:

#include<iostream>
#include<cstdio>
using namespace std;
int n,l,r,w;
int a[2001];
int main() 
{
	freopen("blist.in","r",stdin);
	freopen("blist.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>l>>r>>w;
        for(int j=l;j<=r;j++)
            a[j]+=w;  //累加进来
    }
    int maxx=-1;
    for(int i=1;i<=1000;i++)
        if(maxx<a[i])
            maxx=a[i];  //最大值
    cout<<maxx<<endl;
    return 0;
}

T3:Back and Forth

题目描述

Farmer John有两个挤奶棚,每个挤奶棚里各有一个奶罐和一个装有10个各种尺寸的桶的储物柜。他喜欢将在两个挤奶棚之间来回运送牛奶作为一种锻炼方式。
周一,Farmer John量了恰好1000加仑的牛奶放在第一个挤奶棚的奶罐里,又量了恰好1000加仑的牛奶放在第二个挤奶棚的奶罐里。
周二,他从第一个挤奶棚里取出一个桶,并装满牛奶,然后将牛奶运到第二个挤奶棚,并将牛奶倒进奶罐。他把这个桶留在了第二个挤奶棚。
周三,他从第二个挤奶棚里取出一个桶(可能是周二留在这里的),并装满牛奶,然后将牛奶运到第一个挤奶棚,并将牛奶倒进奶罐。他把这个桶留在了第一个挤奶棚。
周四,他从第一个挤奶棚里取出一个桶(可能是周三留在这里的),并装满牛奶,然后将牛奶运到第二个挤奶棚,并将牛奶倒进奶罐。他把这个桶留在了第二个挤奶棚。
周五,他从第二个挤奶棚里取出一个桶(可能是周二或周四留在这里的),并装满牛奶,然后将牛奶运到第一个挤奶棚,并将牛奶倒进奶罐。他把这个桶留在了第一个挤奶棚。
此时Farmer John测量了第一个挤奶棚的奶罐里的牛奶。他总共可能得到多少种不同的读数?

输入

输入的第一行包含10个整数,为第一个挤奶棚里初始的桶的容积。输入的第二行也包含10个整数,为第二个挤奶棚里初始的桶的容积。所有桶的容积均在1…100的范围内。

输出

输出Farmer John在周五之后测量第一个挤奶棚里的奶罐的牛奶时可能得到的读数的数量。

样例输入

1 1 1 1 1 1 1 1 1 2
5 5 5 5 5 5 5 5 5 5

样例输出

5

分析:

5个,直接每个写出来,不递归
dfs暴力搜索
四重for循环瑟瑟发抖……
不过加了快读以及自定义还是能过,数据较水
枚举5个桶+4重for暴力,过了

CODE:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
#include<vector>
#include<cmath>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)   //自定义
#define dec(i,a,b) for(int i=(a);i>=(b);i--)
#define gc() getchar()
#define endll putchar('\n')
using namespace std;
typedef long long ll;
typedef long double ld;
inline ll read(){  //快读
    char ch=gc();
    ll x=0,f=1;
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=gc();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=gc();
    }
    return x*f;
}
inline void print(ll k){  //快写
    if(k<0) k=-k,putchar('-');
    if(k>9) print(k/10);
    putchar(k%10+48);
}
inline void println(ll k){
    print(k);
    endll;
}
inline void printsp(ll k){
    print(k);
    putchar(' ');
}
set<int> g; 
int b1=1000,b2=1000;
int a[113],b[113];
vector<int> vec2;  //图
int main(){
	freopen("backforth.in","r",stdin);
	freopen("backforth.out","w",stdout);
    rep(i,1,10) a[i]=read();  //分别读入
    rep(i,1,10) b[i]=read();
    rep(i,1,10){
        int t1=a[i];
        b1-=t1;
        a[i]=0; //每个桶の暴力
        b[11]=t1;
        b2+=t1;
        rep(j,1,11){
            int t2=b[j];
            b2-=t2;  //你会发现格式基本一样
            b[j]=0;
            a[11]=t2;
            b1+=t2;
            rep(k,1,11){
                int t3=a[k];
                if(t3==0) continue;  //特判,其它还是一样
                b1-=t3;
                a[k]=0;
                b[12]=t3;
                b2+=t3;
                rep(l,1,12){
                    int t4=b[l];
                    if(t4==0) continue;
                    g.insert(b1+t4);  //插入到这个位置
                }
                b2-=t3;
                b[12]=0;  //再把前面做过的部分清除
                b1+=t3;
                a[k]=t3;
            }
            b1-=t2;
            b2+=t2;
            a[11]=0;  //就是开始的逆操作
            b[j]=t2;
        }
        b1+=t1;
        b2-=t1;  //格式也都一样
        b[11]=0;
        a[i]=t1;
    }
    println(g.size());  //大小即数量
    return 0;
}

猜你喜欢

转载自blog.csdn.net/dgssl_xhy/article/details/106246372