码迷,mamicode.com
首页 > 其他好文 > 详细

May Challenge 2015(CodeChef 2015年5月月赛)

时间:2015-05-19 16:46:41      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:acm   编程   algorithm   算法   codechef   

                                               Chef and new recipe

Rupsa recently started to intern under Chef. He gave her N type of ingredients of varying quantity A1, A2, ..., AN respectively to store it. But as she is lazy to arrange them she puts them all in a storage box.

Chef comes up with a new recipe and decides to prepare it. He asks Rupsa to get two units of each type ingredient for the dish. But when she went to retrieve the ingredients, she realizes that she can only pick one item at a time from the box and can know its type only after she has picked it out. The picked item is not put back in the bag.

She, being lazy, wants to know the maximum number of times she would need to pick items from the box in the worst case so that it is guaranteed that she gets at least two units of each type of ingredient. If it is impossible to pick items in such a way, print -1.

Input

  • The first line of the input contains an integer T denoting the number of test cases.
  • The first line of each test case contains a single integer N denoting the number of different type of ingredients.
  • The second line contains N space-separated integers A1, A2, ..., AN denoting the quantity of each ingredient.

Output

  • For each test case, output a single line containing an integer denoting the answer corresponding to that test case.

Constraints

  • 1 ≤ T ≤ 10
  • 1 ≤ N ≤ 105
  • 1 ≤ Ai ≤ 104

Sub tasks

  • Subtask #1: 1 ≤ N ≤ 1000 (30 points)
  • Subtask #2: original constraints (70 points)

Example

Input:
2
2
2 2
1
6

Output:
4
2

Explanation

  • In Example 1, she need to pick up all items.
  • In Example 2, since there is only one type of ingredient, picking two items is enough.

题目大意
    一个罐子里有n个食材,每个食材取2单位,每次他从罐子内取1单位,求最多需多少次?

题解:
     让最少的食材最后取就可以了。

代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int inf=0x7fffffff;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int sum=0,minx=inf,n;
        scanf("%d",&n);
        int x;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&x);
            if(x<minx)
            minx=x;
            sum+=x;
        }
        if(minx<2)
        printf("-1\n");
        else
        printf("%d\n",sum-minx+2);
    }
    return 0;
}



                                                Set Difference 

Churu is working as a data scientist in Coderpur. He works on a lot of data on the daily basis. One day, he found an interesting problem, which was very easy to solve for small data but was getting more complex with increasing number of data points. So, Churu needs your help in solving this problem.

Given a set S of N non-negative integers (Some integers might occur more than once in the set), find out the value of SETDIFF(S).

技术分享

Where max(s) represents the maximum value in set s whereas min(s) represents the minimum value in the set s.
As value of SETDIFF(S) can be very large, print it modulo (109 + 7) .

There might be repeated values in the set. For set S = {1,2,2}, consider that first 2 is not same as the second 2 and there will be two different subsets {1,2}. See last sample case for the more clarifications.

Input

  • First line of input contains an integer T denoting number of test cases.
  • For each test case, first line will contain an integer N denoting number of elements in set S.
  • Next line contains N space separated integers denoting the set S.

Output

For each test case, print a single integer representing the answer of that test case.

Note

Two subsets will be called different if there exists an index i such that S[i] occurs in one of the subset and not in another.

Constraints

Subtask #1: 20 points

  • 1 ≤ T ≤ 5, 1 ≤ N ≤ 1000, 0 ≤ value in set ≤ 109

Subtask #2: 25 points

  • 1 ≤ T ≤ 5, 1 ≤ N ≤ 105, 0 ≤ value in set ≤ 1000

Subtask #3: 55 points

  • 1 ≤ T ≤ 5, 1 ≤ N ≤ 105, 0 ≤ value in set ≤ 109

Example

Input:
4
2
1 2
3
1 2 3
4
1 2 3 4
3
1 2 2

Output:
1
6 
23
3

Explanation

For first case answer will be 2-1 = 1.

For the second case:

Subset = {1}, max(s)-min(s) = 0.
Subset = {2}, max(s)-min(s) = 0.
Subset = {3}, max(s)-min(s) = 0.
Subset = {1,2}, max(s)-min(s) = 1.
Subset = {2,3}, max(s)-min(s) = 1.
Subset = {1,3}, max(s)-min(s) = 2.
Subset = {1,2,3}, max(s)-min(s) = 2.
So the output will be 1+1+2+2 = 6.

In the last case, there are three subsets, {1,2}, {1,2} and {1,2,2} having max(s) - min(s) = 1 for each.



题目大意
       s集合的所有子集的最大值与最小值差的和。

题解:
          排个序,枚举最大值,最小值,有k个比要枚举的数小的,就有2^k个子集,将最大值的和加起来减去最小值
的和就可以了。

代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=100000+100;
const int mod=1e9+7;
long long p[maxn];
int a[maxn];
int main()
{
    p[0]=1;
    for(int i=1;i<maxn;i++)
    p[i]=(p[i-1]*2)%mod;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
        sort(a,a+n);
        int ans=0;
        for(int i=n-1;i>=0;i--)
        {
            ans=(ans+((long long)a[i]*p[i])%mod)%mod;
        }
        for(int i=0;i<n;i++)
        ans=(ans-((long long)a[i]*p[n-i-1])%mod+mod)%mod;

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

                                    Chef and Prime Divisors

You are given two positive integers – A and B. You have to check whether A is divisible by all the prime divisors of B.

Input

The first line of the input contains an integer T denoting the number of test cases. The description of Ttest cases follows.

For each test case, you are given two space separated integers – A and B.

Output

For each test case, output "Yes" (without quotes) if A contains all prime divisors of B, otherwise print "No".

Constraints

  • 1 ≤ T ≤ 104
  • 1 ≤ A, B ≤ 1018

Subtasks

  • Subtask 1 (20 points):1 ≤ B ≤ 107
  • Subtask 2 (30 points):1 ≤ A ≤ 107
  • Subtask 3 (50 points): Original constraints

Example

Input:
3
120 75
128 16
7 8

Output:
Yes
Yes
No

Explanation

Example case 1. In the first case 120 = 23*3*5 and 75 = 3*52. 120 is divisible by both 3 and 5. Hence, we will print "Yes"

Example case 2. In the second case both 128 and 16 are powers of two. Hence, the answer is "Yes"

Example case 3. In the third case 8 is power of two and 7 is not divisible by 2. So, the answer is "No"



题目大意:
     给两个数A和B,判断A是否能被B的所有质因数整除。

题解:
     A和B的值较大,直接找B的所有质因数会超时,我们可以取两个的最大公约数,它们的公约数肯定是由B的质因数相乘得到的,且能被A整除,于是B就可以去除这部分质因数,B=B/gcd(A,B),直到A,B两个的公约数为1,如果此时B为1,A能被B的所有质因数整除,否则不能。


代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
long long gcd(long long a,long long b)
{
    return b==0?a:gcd(b,a%b);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long n,m;
        scanf("%lld%lld",&n,&m);
        int sign=1;
        if(n%m!=0)
        {
            while(1)
            {
                if(n%m==0)
                    break;
                long long k=gcd(n,m);
                if(k==1)
                {
                    sign=0;
                    break;
                }
                else
                {
                    while(m%k==0)
                        m=m/k;
                }
            }
        }
        if(sign)
        printf("Yes\n");
        else
        printf("No\n");

    }
}


                                     Devu and binary String 


Devu loves to play with binary strings a lot. One day he borrowed a binary string s of size n from his friend Churu. Before starting to play with it, he wants to make sure that string does not contain more than k consecutive equal characters. For achieving that, only kind of operation he is allowed to perform is to flip any ith character of the string.

As Devu is always in hurry to meet his girlfriend, he wants you to help him in finding out the minimum number of operations he will need. Also he wants you to print one of the possible modified string too.

Input

  • First line of input contains an integer T denoting the number of test cases.
  • For each test case, there are two lines.
  • First line contains two space separated integers n, k as defined in the problem.
  • Next line contains string s of size n.

Output

  • For each test case, print two lines.
  • First line should contain an integer corresponding to minimum number of operations Devu needs.
  • In second line, print one of the possible modified strings.

Constraints

Subtask #1: 20 points

  • 1 ≤ T ≤ 1001 ≤ n ≤ 201 ≤ k ≤ n

Subtask #2: 35 points

  • 1 ≤ T ≤ 1021 ≤ n ≤ 1031 ≤ k ≤ n

Subtask #3: 45 points

  • 1 ≤ T ≤ 1051 ≤ n ≤ 1051 ≤ k ≤ n
  • Sum of n over all the test cases is ≤ 106

Example

Input:
3
2 1
11
2 2
11
4 1
1001

Output:
1
10
0
11
2
1010

Explanation

Example case 1: As 1 is occurring twice consecutively, we can convert 11 to 10 in a single operation.

Example case 2: You don‘t need to modify the string as it does not have more than 2 equal consecutive character.

Example case 3: As 0 is occurring twice consecutively, we can convert 1001 to 1010 in a two operations (Flip third and fourth character).




题目大意:
    长度为n的01串,每次操作只能翻转一个字符,求最少操作数,使其不含超过k个连续的相同的字符。

题解:
    如果连续的长度超过k个了,这时就需要翻转了,到底要翻转哪个呢?这就需分类讨论下了,假如第k+1个相同字符的位置是i,后是是与它相同的字符,这时只需翻转i位置最优,假如后面的与它不同,此时翻转当前位置可能导致后面的串长度超了,就不会最优了,此时就需要翻转i-1了,既将前面分成了不超过k的连续相同的串,又不会对后面的造成影响。
   还有,此策略对k==1的不适用,i-1会对前面的造成影响,k==1时的特殊考虑下就可以了,肯定是01相间的,取最小的就可以了。

代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=100000+1000;
int s[maxn];
int a[maxn];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,k;
        scanf("%d%d",&n,&k);
        char temp;
        getchar();
        for(int i=0; i<n; i++)
        {
            scanf("%c",&temp);
            s[i]=temp-'0';
        }
        int cur=1;
        int ans=0;
        int cnt=s[0];
        if(k!=1)
        {
            for(int i=1; i<n; i++)
            {
                if(s[i]==cnt)
                {
                    cur++;
                }
                else
                {
                    cur=1;
                    cnt=s[i];
                }
                if(cur==k+1&&i<n-1&&s[i+1]==cnt)
                {
                    s[i]=!s[i];
                    cur=0;
                    ans++;
                }
                if(cur==k+1&&i<n-1&&s[i+1]!=cnt)
                {
                    ans++;
                    s[i-1]=!s[i-1];
                    cur=1;
                }
                if(cur==k+1&&i==n-1)
                {
                    ans++;
                    s[i]=!s[i];
                }
            }
        }
        else
        {
            for(int i=1;i<n;i++)
            {
                if(s[i]!=(!s[i-1]))
                {
                    ans++;
                    s[i]=!s[i-1];
                }
            }
        }
        if(n-ans>=ans)
        {
        printf("%d\n",ans);
        for(int i=0; i<n; i++)
            printf("%d",s[i]);
        printf("\n");
        }
        else
        {
            printf("%d\n",n-ans);
            for(int i=0;i<n;i++)
            printf("%d",!s[i]);
            printf("\n");
        }
    }
    return 0;
}


                                          Chef and Cake 

The Chef once decided to prepare some nice dishes on his birthday. There are N items kept on his shelf linearly from position 1 to N. Taste of the i-th item is denoted by a integer Ai.

He wants to make Q dishes. A dish will be made using some ingredients in the continuous range AL, AL + 1, , , AR (1-base indexing). Quality of the dish will be determined by the ingredient with minimum taste.

Chef wants help of his assistant Rupsa to find out sum and product of qualities of the dishes. As product of the qualities of the dishes could be very large, print it modulo 109 + 7. Also, you are given an integerK and you are assured that for each dish, the size of continuous range of the ingredients (i.e. R - L + 1) will always lie between K and 2 * K, both inclusive.

Method of generation of Array A 
You are given non-negative integer parameters a, b, c, d, e, f, r, s, t, m, A[1]


for x = 2 to N:
	if(t^x mod s  <= r)        // Here t^x signifies "t to the power of x"
		A[x] = (a*A[x-1]^2 + b*A[x-1] + c) mod m
	else
		A[x] = (d*A[x-1]^2 + e*A[x-1] + f) mod m

Method of generation of range of ingredients for Q dishes 
You are given non-negative integer parameters L1, La, Lc, Lm, D1, Da, Dc, Dm


for i = 1 to Q:
	L1 = (La * L1 + Lc) mod Lm;
	D1 = (Da * D1 + Dc) mod Dm; 
	L = L1 + 1;
	R = min(L + K - 1 + D1, N);

Input

  • The first line contains three integers NK and Q.
  • The second line contains the integers a, b, c, d, e, f, r, s, t, m, and A[1].
  • Then third line contains the integers L1, La, Lc, Lm, D1, Da, Dc, and Dm

Output

Output two space separated integers:

  • The sum of qualities of the dishes.
  • The product of qualities of the dishes modulo 109+7.

Constraints

  • 1 ≤ N, Q ≤ 107
  • 1 ≤ K ≤ N
  • 0 ≤ a, b, c, d, e, f, r, s, t, m, A[1] ≤ 109+7
  • 1 ≤ Lm ≤ N - K + 1
  • 1 ≤ Dm ≤ K + 1
  • 1 ≤ La, Lc ≤ Lm
  • 1 ≤ Da, Dc ≤ Dm
  • 1 ≤ L1 ≤ N
  • 1 ≤ D1 ≤ K

Sub tasks

  • Subtask #1: 1 ≤ N, Q ≤ 1000 (10 points)
  • Subtask #2: 1 ≤ Q ≤ 104 (20 points)
  • Subtask #3: original constraints (70 points)

Example

Input:
4 2 1
1 1 1 1 1 1 1 1 1 100 1 
1 1 1 3 1 1 1 2

Output:
13 13

Explanation

  • The array A comes out to be {1, 3, 13, 83} and the first dish has L = 3 and R = 4. The minimum in this range is 13, thus the sum and product both are 13 and hence the answer.

Note

Multiplier for C# and Java have been reduced to 1.5 instead of 2.



题目大意:
     生成长度为n的数组,有Q个查询,查询[L,R]区间内的最小值,求这Q个查询的最小值的和与积,区间长度在k与2*k间。

题解:
    RMQ算法,由于区间长度在k与2*k间,维护一个区间长度为k的最小值,查询的时候就可以取[L,L+k],[R-k+1,R]两端区间的最小值,做到O(1)查询。

代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1e7+1000;
const int mod=1e9+7;
long long A[maxn];
int cnt[maxn];
int rmq[maxn];
int main()
{
    int n,k,q;
    while(~scanf("%d%d%d",&n,&k,&q))
    {
        long long a,b,c,d,e,f,r,s,t,m;
        scanf("%lld%lld%lld%lld%lld%lld%lld%lld%lld%lld%lld",&a,&b,&c,&d,&e,&f,&r,&s,&t,&m,&A[1]);
        long long cur=t;
        long long L1,La,Lc,Lm,D1,Da,Dc,Dm;
        int L,R;
        scanf("%lld%lld%lld%lld%lld%lld%lld%lld",&L1,&La,&Lc,&Lm,&D1,&Da,&Dc,&Dm);
        for(int i=2; i<=n; i++)
        {
            cur=(cur*t)%s;
            if(cur<=r)
                A[i] = ((a*(A[i-1]*A[i-1])%m)%m + (b*A[i-1]%m) + c) % m;
            else
                A[i] = ((d*(A[i-1]*A[i-1])%m)%m + (e*A[i-1])%m + f) % m;
        }
        int front=1,rear=0;
        for(int i=1;i<=n;i++)
        {
            while(front<=rear&&i-cnt[front]+1>k)
            ++front;
            while(front<=rear&&A[i]<=A[cnt[rear]])
            --rear;
            cnt[++rear]=i;
            if(i>=k)
            rmq[i-k+1]=A[cnt[front]];
        }
        long long ans=1,sum=0;
        long long temp;
        for(int i=0; i<q; i++)
        {
            L1 = ((La * L1)%Lm + Lc) % Lm;
            D1 = ((Da * D1)%Dm + Dc) % Dm;
            L =(int)L1 + 1;
            R = min(L + k - 1 + (int)D1, n);
            temp=min(rmq[L],rmq[R-k+1]);
            sum+=temp;
            ans=(ans*temp)%mod;
        }
        printf("%lld %lld\n",sum,ans);
    }
    return 0;
}



May Challenge 2015(CodeChef 2015年5月月赛)

标签:acm   编程   algorithm   算法   codechef   

原文地址:http://blog.csdn.net/caduca/article/details/45844051

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!