Codeforces Round #256 (Div. 2)A-D

畫船聽雨發表於2014-08-23

題目連線:http://codeforces.com/contest/448

A:給你一些獎盃與獎牌讓你判斷能不能合法的放在給定的架子上。如果可以就是YES否則就是NO。

<span style="font-size:18px;">#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-12
///#define M 1000100
///#define LL __int64
#define LL long long
///#define INF 0x7ffffff
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
#define zero(x) ((fabs(x)<eps)?0:x)

using namespace std;

const int maxn = 100010;

int num[maxn];

int main()
{
    int a1, a2, a3;
    int b1, b2, b3;
    int n;
    while(cin >>a1)
    {
        cin >>a2>>a3;
        cin >>b1>>b2>>b3;
        cin >>n;
        int sum1 = 0;
        sum1 += a1;
        sum1 += a2;
        sum1 += a3;
        int sum2 = 0;
        sum2 += b1;
        sum2 += b2;
        sum2 += b3;
        int x = sum1/5;
        if(sum1%5) x++;
        int y = sum2/10;
        if(sum2%10) y++;
        if(x+y<= n) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}</span>

B:給你兩個字串,判斷如果讓s串變成t串需要什麼操作。如果只是刪除一些字母就可以得到輸出:automaton。如果只是通過調換字母的順序就輸出:array。如既要刪除字母又要調換順序輸出:both。如果需要新增新的字母輸出:need tree。

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-12
///#define M 1000100
///#define LL __int64
#define LL long long
///#define INF 0x7ffffff
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
#define zero(x) ((fabs(x)<eps)?0:x)

using namespace std;

const int maxn = 110;

char s1[maxn];
char s2[maxn];
int vis[maxn];
int num[maxn];

int main()
{
    while(cin >>s1)
    {
        cin >>s2;
        int len1 = strlen(s1);
        int len2 = strlen(s2);
        memset(vis, 0, sizeof(vis));
        memset(num, 0, sizeof(num));
        for(int i = 0; i < len1; i++) vis[s1[i]-'a']++;
        int flag1 = 0;
        for(int i = 0; i < (len1-len2); i++)
        {
            int flag = 0;
            for(int j = 0; j < len2; j++)
            {
                if(s1[i+j] != s2[j])
                {
                    flag = 1;
                    break;
                }
            }
            if(!flag)
            {
                flag1 = 1;
                break;
            }
        }
        int flag2 = 0;
        for(int i = 0; i < len2; i++) num[s2[i]-'a']++;
        for(int i = 0; i < 26; i++)
        {
            if(num[i] > vis[i])
            {
                flag2 = 1;
                break;
            }
        }
        if(flag2) cout<<"need tree"<<endl;
        else if(flag1) cout<<"automaton"<<endl;
        else if(len1 == len2 && !flag2) cout<<"array"<<endl;
        else
        {
            int top = 0;
            for(int i = 0; i < len1; i++) if(s1[i] == s2[top]) top++;
            if(top == len2) cout<<"automaton"<<endl;
            else cout<<"both"<<endl;
        }
    }
}

C給你一串數字代表木板的高度,每塊木板的寬度都為1。讓你算出最少需要多少次可以把木板染完顏色。染得時候可以每次染長度為1的一橫行(可以多個連續的木板)或者可以豎著然這個一塊木板。每個木板可以重複染色。

思路是:dp[i][j]表示染到第i塊木板的時候染了j次橫的。

需要注意的是要從後向前的dp。

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-12
///#define M 1000100
///#define LL __int64
#define LL long long
///#define INF 0x7ffffff
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
#define zero(x) ((fabs(x)<eps)?0:x)

using namespace std;

const int maxn = 5010;
int dp[maxn][maxn];
int num[maxn];
int main()
{
    int n;
    while(cin >>n)
    {
        num[0] = 0;
        for(int i = 1; i <= n; i++) scanf("%d",&num[i]);
        for(int i = 0; i <= n; i++) dp[n][i] = 0;
        for(int i = n; i >= 1; i--)
        {
            for(int j = 0; j < i; j++)
            {
                if(num[i] <= num[j])
                {
                    dp[i-1][j] = dp[i][i];
                    continue;
                }
                dp[i-1][j] = min(dp[i][j]+1, dp[i][i]+num[i]-num[j]);
            }

        }
       cout<<dp[0][0]<<endl;
    }
    return 0;
}

D給你n,m,k。n*m的矩陣中的每個元素是i,j的成績。然後讓你求一個x滿足在這個n*m的矩陣中有k個元素小於x。

思路二分列舉x,範圍是1-n*m。但是這裡要快速求出小於x的數的個數。

 for(int i = 1; i <= n; i++) ans += min(m, mid/i);這個可以快速的統計出這一行中有多少個元素是小於x的。

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-12
///#define M 1000100
///#define LL __int64
#define LL long long
///#define INF 0x7ffffff
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
#define zero(x) ((fabs(x)<eps)?0:x)

using namespace std;

const int maxn = 5010;
int dp[maxn][maxn];
int num[maxn];
int main()
{
    LL n, m, k;
    while(cin >>n>>m>>k)
    {
        LL l = 1;
        LL r = n*m;
        while(l < r)
        {
            LL mid = (l+r)>>1;
            LL ans = 0;
            for(int i = 1; i <= n; i++) ans += min(m, mid/i);
            if(ans >= k) r = mid;
            else if(ans < k) l = mid+1;
        }
        cout<<r<<endl;
    }
}


相關文章