cf#350 div2

A题

http://codeforces.com/contest/670/problem/A

题意:

给你一年的天数,问你最多最少几个周六周日。。竟然wa了一次,忘记考虑%7 = 6的情况了,6天的时候是一定要有个周六或者周日的

By zjyhala, contest: Codeforces Round #350 (Div. 2), problem: (A) Holidays, Accepted, #
 #include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int main()
{
    int n;
    scanf("%d",&n);
    int ans = n % 7;
    int k =n/ 7 * 2;

    if(ans == 0)
        cout << k<< " " << k << endl;
    else if(ans == 1)
        cout << k <<" " << k+1 << endl;
    else if(ans == 6)
        cout << k+1 << " " << k+2 << endl;
    else
           cout << k << " " << k+2 << endl;
    return 0;
}

B题

尴尬,tle了好几次,太暴力了。。。
http://codeforces.com/contest/670/problem/B

题意:

每个人都有自己的数字
现在在玩一个游戏,叫做叫数字
每个人都会叫前面所有人的名字和自己的名字
现在问你第k个叫的名字是啥。。。。

第一次想的是单纯的模拟,然后就逗比了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
const int maxn = 100010;
int a[maxn];
using namespace std;

int main()
{
    int n,k;
    scanf("%d%d",&n,&k);

    for(int i = 0 ; i < n ;i++)
        scanf("%d",&a[i]);

    int ans = 0,flag = 0;
    for (int i = 1; i < sqrt((double) 2*k)+1 ; i++)
    {
        for (int j = 0 ; j < i ;j++)
           {
                ans ++;
                if(ans == k)
                   {
                        flag = a[j];
                        break;
                   }
           }
        if(flag)
            break;
    }

    printf("%d\n",flag);
    return 0;
}

tle不需要理由,其实上面的二重循环,除了最后一次有用处之外,完全是浪费程序的人生,直接模拟加上i就好了,等到超过要的k的时候减回去就好了嘛。。好蠢

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
const int maxn = 100010;
int a[maxn];
using namespace std;

int main()
{
    int n,k;
    scanf("%d%d",&n,&k);

    for(int i = 0 ; i < n ;i++)
        scanf("%d",&a[i]);

    int ans = 0;
    for (int i = 1; i < sqrt((double) 2*k)+1 ; i++)
    {
        ans += i;
       if(ans >= k)
           {
                ans = i-(ans-k);
                break;
           }
    }

    printf("%d\n",a[ans-1]);
    return 0;
}

C题

http://codeforces.com/contest/670/problem/C

题意:

n个科学家 相应的懂一门语言 m部电影 有对应的音频和字幕 语言不同 当科学家听懂一部电影(同音频语言)时 他很满意 看懂一部电影(同字幕语言)是比较满意 什么都不懂时 不满意 。 问 播放哪一部电影 使得满意的科学家最多 (当满意的科学家的个数相同时 输出 比较满意的科学家的个数多的电影)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
const int maxn = 210010;
int m,mov[maxn],mos[maxn],a[maxn];
using namespace std;

map <int,int> mp;
int main()
{
    int tn,mn;
    scanf("%d",&tn);
    int maxo = 0;
    for (int i = 0 ; i < tn ;i++)
       {
            scanf("%d",&m);
            if(mp.count(m) == 0)
                mp[m] = 0;
            mp[m]++;
       }

       scanf("%d",&mn);
    for (int i = 0 ; i < mn ;i++)
        scanf("%d",&mov[i]);
    for (int i = 0 ; i < mn ;i++)
        scanf("%d",&mos[i]);

    int ans = 0;
    for (int i = 0 ; i < mn ;i++)
    {
        if(mp[mov[i]] > maxo)
        {
            maxo = mp[mov[i]];
            ans = i;
        }
        else if(mp[mov[i]] == maxo)
        {
            if(mp[mos[i]] > mp[mos[ans]])
                ans = i;
        }
    }
    cout << ans+1 << endl;
    return 0;
}

D1题

http://codeforces.com/contest/670/problem/D1

题意:

要做饼干,每个饼干需要m种不同的的原料,每种原料需要a[i],你现在每种原料有b[i],你现在还有K个魔法粉,一个魔法粉可以转化为任何一个单位的原料,问最多做多少饼干?

思路:

优先队列,按照能做成的饼干数加入,每次在最少的上加万能原料,再加入队列。

#include <iostream>
#include <cstdio>
#include <queue>
#include <functional>
#include <vector>
#include <utility>
const int maxn = 2e5+10;
using namespace std;

struct node
{
    int need,have,num,kk;
     bool operator < (const node &b)const
    {
        return num > b.num;
    }

}a[maxn];

priority_queue < node> pq;

int main()
{
    int n , k;
    scanf("%d%d",&n,&k);
    for (int i = 0 ; i < n ;i++)
        scanf("%d",&a[i].need);
    for (int i = 0 ; i < n;i++)
        scanf("%d",&a[i].have);
   for (int i = 0 ; i < n ;i++)
   {
      a[i].num = a[i].have / a[i].need ;
      a[i].kk = a[i].need - a[i].have % a[i].need;
      pq.push(a[i]);
   }

   int ans = pq.top().num;
   while (k>0 && !pq.empty())
   {
        node m = pq.top();
      // cout <<k << endl;
       if(m.kk <= k)
       {

            pq.pop();
            k -= m.kk;
            m.num++;
            m.have += m.kk;
            m.kk = m.need;
            ans = m.num;
            pq.push(m);
       }
       else
            break;
   }

    ans = min(ans, pq.top().num);
   cout << ans <<endl;
    return 0;
}

D2题

除了数据范围和上一题一样,最大可能值是2e9,二分可能答案,写判断函数,复杂度 O(log(n))

两个代码都ac了。。。


#include <iostream>
#include <cstdio>
#include <algorithm>
const int maxn = 100010;
int need[maxn],have[maxn];
int n;

using namespace std;

int isok(long long  mid,int k)
{
    long long  kk = k;

    for (int i = 0 ; i < n ;i++)
    {
        long long ans = mid * need[i] - have[i] ;

        if(ans > 0)
        {
            kk -= ans;

            if(kk < 0)
                return 0;
        }
    }
    return 1;
}



int main()
{
    int k;
    scanf("%d%d",&n,&k);

    for (int i = 0 ; i < n ;i++)
        scanf("%d",&need[i]);
    for (int i = 0 ; i < n ;i++)
        scanf("%d",&have[i]);

    long long left = 0,right = 2e9;
    while (1)
    {
        long long  mid = (left+right) /2;

        if(right - left == 1 || right == left)
            break;
        if(isok(mid,k))
            left = mid;
        else
            right = mid;
    }

    int ans = left;
    if(left != right)
        if(isok(right,k))
            ans = right;
    cout << ans << endl;
    return 0;
}

注意传的函数参数mid虽然肯定不会超过int ,但是传的一定要用LL接,不然就发现ans变成了负数,爆了,即使开的是LL。。。一定要记住教训,4个小时啊。。。

二分有比较标准的写法,上面的会浪费查mid;

#include <iostream>
#include <cstdio>
#include <algorithm>
const int maxn = 100010;
int need[maxn],have[maxn];
int n;

using namespace std;

int isok(long long  mid,int k)
{
    long long  kk = k;

    for (int i = 0 ; i < n ;i++)
    {
        long long ans = mid * need[i] - have[i] ;

        if(ans > 0)
        {
            kk -= ans;

            if(kk < 0)
                return 0;
        }
    }
    return 1;
}



int main()
{
    int k;
    scanf("%d%d",&n,&k);

    for (int i = 0 ; i < n ;i++)
        scanf("%d",&need[i]);
    for (int i = 0 ; i < n ;i++)
        scanf("%d",&have[i]);

    long long left = 0,right = 2e9;
    while (left<=right)
    {
        long long  mid = (left+right) /2;
        if(isok(mid,k))
            left = mid+1;
        else
            right = mid-1;
          // cout << mid << endl;
    }

    int ans = left;
    if(left != right)
        if(isok(right,k))
            ans = right;
    cout << ans << endl;
    return 0;
}

你可能感兴趣的:(cf#350 div2)