Codeforces Round 256 (Div. 2)

传送门

A.A - Rewards (签到)

题意

三种A物品,三种B物品;

容器一次只能装五个A或者十个B不能同时装A和B

思路

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+9;
const int maxn=3e5+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int a=0,b=0;
    for(int i=1;i<=3;i++){
        int aa;cin>>aa;
        a+=aa;
    }
    for(int i=1;i<=3;i++){
        int aa;cin>>aa;
        b+=aa;
    }
    int n;cin>>n;
    int num1=a/5+(a%5?1:0);
    int num2=b/10+(b%10?1:0);
    cout<<(num1+num2<=n?"YES":"NO");
    return 0;
}

B - Suffix Structures (分类讨论)

题意

让你判断字符串A能否变成字符串B

如果字符串A能通过删去某些数变成B 输出巴拉巴拉

如果字符串A能通过对调某个数变成B 输出巴拉巴拉

如果字符串A同时需要上面两个操作才能变成B 输出巴拉巴拉

如果字符串A通过上面两个操作都不能变B 输出巴拉巴拉

思路

还有啥,直接模拟呗

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+9;
const int maxn=3e5+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
string s,t;
int a[maxn];
int b[maxn];
bool find(){
    int pos=0;
    for(int i=0;i<t.size();i++){
        bool ok=false;
        int j;
        for(j=pos;j<s.size();j++){
            if(s[j]==t[i]){ok=true;break;}
        }
        if(!ok)return false;
        else pos=j+1;
    }
    return true;
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    cin>>s>>t;
    int len1=s.size(),len2=t.size();
    for(int i=0;i<len1;i++){
        a[s[i]-'a']++;
    }
    for(int i=0;i<len2;i++){
        b[t[i]-'a']++;
    }
    int flag=0;
    for(int i=0;i<26;i++){
        if(a[i]==b[i])continue;
        if(a[i]<b[i])cout<<"need tree",exit(0);
        else{
            flag=1;
        }
    }
    if(!flag){
        puts("array");return 0;
    }
    if(flag){
        if(find())
            puts("automaton"),exit(0);
        else{
            puts("both");return 0;
        }
    }
    return 0;
}

C - Painting Fence(分治)

题意

给出一排木板,木板的高度为A[i],宽度为1.

你手里有一个大小为1的刷子,你每次可以一次性刷一条不间断直线

问你最少刷几次可以把这一排木板刷完

思路

首先 假设如果我们全部横着刷

那么我们就需要最爱的木板高度+其他凸出来的次数

假设我们数着刷那么我们就需要刷木板的个数

所以我们就只要这两种情况取个优

再判断横着刷的时候 凸出来的需要另外考虑 这又是一个小问题,所以我们可以分治去做

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+9;
const int maxn=3e5+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
int n;
ll a[maxn];
ll dfs(int s,int t){
    if(s>t)return 0;
    ll mi=inf,need=0;
    for(int i=s;i<=t;i++){
        mi=min(a[i],mi);
    }
    need+=mi;
    for(int i=s;i<=t;i++)
        a[i]-=mi;
    int st=s;
    for(int i=st;i<=t;i++)
        if(i==t&&a[i])
            need+=dfs(st,i),st=i+1;
        else if(!a[i])
            need+=dfs(st,i-1),st=i+1;
    return min(1LL*(t-s+1LL),need);
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    cout<<dfs(1,n);
    return 0;
}

D.D - Multiplication Table (二分)

题意

对于一个乘法表 求出第K大的数是多少

思路

我们发现对于一行或者一列他们的值都是递增的 所以满足二分的性质

于是我们二分答案;

可以求出每一行有多少个值小于这个答案

include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+9;
const int maxn=3e5+50;
const ll inf=0x3f3f3f3f3f3f3f3fLL;

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    ll n,m,k;cin>>n>>m>>k;
    ll l=0,r=n*m,ans=-1;
    while(l<=r){
        ll mid=(l+r)/2;
        ll sum=0;
        for(int i=1;i<=n;i++)
            sum+=min(m,(mid-1)/i);
        if(sum<k){
            l=mid+1;
            ans=mid;
        }
        else
            r=mid-1;
    }
    cout<<ans;
    return 0;
}

E - Divisors (dfs)

题意

定义一个函数为F(a){a为一个数组}

F(a)的值为a的元素的所有因数依次排列

定义一个数组P[a]

P[i]的递推式为P[i]=P(X[i-1])

现在给你P[0]让你求出P[k];

思路

很明显这个P是递归的,而且只需要输出前1e5项,那么我们就直接暴力枚举因子就行

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=1e6+10;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
vector<ll>ve;
int len;
ll num;
void dfs(ll n,ll k){
    if(num>=1e5)return;
    if(k==0||n==1){
        num++;
        cout<<n<<" ";
        return ;
    }
    for(ll i=0;i<ve.size()&&ve[i]<=n;i++)
        if(n%ve[i]==0)dfs(ve[i],k-1);
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    ll x,k;
    cin>>x>>k;
    for(ll i=1;i*i<=x;i++){
        if(x%i==0){
            ve.push_back(i);
            if(i*i!=x)ve.push_back(x/i);
        }
    }
    sort(ve.begin(),ve.end());
    len=ve.size();
    dfs(x,k);
    return 0;
}
posted @ 2019-03-02 00:24  luowentao  阅读(196)  评论(0编辑  收藏  举报