1. 程式人生 > >組隊賽(第七週)

組隊賽(第七週)

ABDE為水題,CF為dp

A - Nth Largest Value

4552 Nth Largest Value
For this problem, you will write a program that prints the N-th largest value in a fixed sized array
of integers. To make things simple, N will be 3 and the array will always be have 10 decimal integer
values.
Input
The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets
that follow. Each data set consists of a single line containing the data set number, followed by a space,
followed by 10 space separated decimal integers whose values are between 1 and 1000 inclusive.
Output
For each data set, generate one line of output with the following values: The data set number as a
decimal integer, a space, and the 3rd largest value of the corresponding 10 integers.
Sample Input
4
1 1 2 3 4 5 6 7 8 9 1000
2 338 304 619 95 343 496 489 116 98 127
3 931 240 986 894 826 640 965 833 136 138
4 940 955 364 188 133 254 501 122 768 408
Sample Output
1 8
2 489
3 931
4 768
題意:水題)找第三大的數

#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
typedef long long LL;
using namespace std;
int main()
{
   int a[1010];
   int n,t=1,x;
   cin>>n;
   while(n--)
   {
       cin>>x;
       for(int i=0;i<10;i++)
            cin>>a[i];
       sort(a,a+10);
       cout<<x<<" "<<a[7]<<endl;
   }


    return 0;
}

B - Equal Sum Partitions

An equal sum partition of a sequence of numbers is a grouping of the numbers (in the same order
as the original sequence) in such a way that each group has the same sum. For example, the sequence:
2 5 1 3 3 7
may be grouped as:
(2 5) (1 3 3) (7)
to yield an equal sum of 7.
Note: The partition that puts all the numbers in a single group is an equal sum partition with the
sum equal to the sum of all the numbers in the sequence.
For this problem, you will write a program that takes as input a sequence of positive integers and
returns the smallest sum for an equal sum partition of the sequence.
Input
The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets
that follow. The first line of each data set contains the data set number, followed by a space, followed
by a decimal integer M, (1 ≤ M ≤ 10000), giving the total number of integers in the sequence. The
remaining line(s) in the dataset consist of the values, 10 per line, separated by a single space. The last
line in the dataset may contain less than 10 values.
Output
For each data set, generate one line of output with the following values: The data set number as a
decimal integer, a space, and the smallest sum for an equal sum partition of the sequence.
Sample Input
3
1 6
2 5 1 3 3 7
2 6
1 2 3 4 5 6
3 20
1 1 2 1 1 2 1 1 2 1
1 2 1 1 2 1 1 2 1 1
Sample Output
1 7
2 21
3 2
找這一堆數能夠分成幾個集合,使得每個集合的所有元素的和是相等的,必須是相鄰的數才能劃分到一個集合中

#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
typedef long long LL;
using namespace std;
int a[1010];
int n,m;
int main()
{
   ios::sync_with_stdio(false);
   int t,sum1,sum;
   cin>>t;
   while(t--)
   {
       int ans=0;
       sum1=0,sum=0;
       cin>>n>>m;
       for(int i=1;i<=m;i++)
       {
           cin>>a[i];
           sum+=a[i];
       }
       for(int i=1;i<=sum;i++)
       {
           sum1=0;
           for(int j=1;j<=m;j++)
           {
               sum1+=a[j];
               if(sum1==i)
               {
                   sum1=0;
               }
               else if(sum1>i)
               {
                   break;
               }
           }
           if(sum1!=0)
           {
               continue;
           }
           else
           {
               ans=i;
               break;
           }
       }
       cout<<n<<" "<<ans<<endl;
   }
    return 0;
}

C- Balls

4554 Balls
The classic Two Glass Balls brain-teaser is often posed as:
“Given two identical glass spheres, you would like to determine the lowest floor in a 100-story
building from which they will break when dropped. Assume the spheres are undamaged
when dropped below this point. What is the strategy that will minimize the worst-case
scenario for number of drops?”
Suppose that we had only one ball. We’d have to drop from each floor from 1 to 100 in sequence,
requiring 100 drops in the worst case.
Now consider the case where we have two balls. Suppose we drop the first ball from floor n. If it
breaks we’re in the case where we have one ball remaining and we need to drop from floors 1 to n − 1
in sequence, yielding n drops in the worst case (the first ball is dropped once, the second at most n − 1
times). However, if it does not break when dropped from floor n, we have reduced the problem to
dropping from floors n + 1 to 100. In either case we must keep in mind that we’ve already used one
drop. So the minimum number of drops, in the worst case, is the minimum over all n.
You will write a program to determine the minimum number of drops required, in the worst case,
given B balls and an M-story building.
Input
The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets that
follow. Each data set consists of a single line containing three (3) decimal integer values: the problem
number, followed by a space, followed by the number of balls B, (1 ≤ B ≤ 50), followed by a space and
the number of floors in the building M, (1 ≤ M ≤ 1000).
Output
For each data set, generate one line of output with the following values: The data set number as a
decimal integer, a space, and the minimum number of drops needed for the corresponding values of B
and M.
Sample Input
4
1 2 10
2 2 100
3 2 300
4 25 900
Sample Output
1 4
2 14
3 24
4 10
題意:有一個大樓,他有n層,有m個雞蛋,如果在第i層扔一個雞蛋沒碎,但是在第i+1層扔一個雞蛋碎了,那麼這個雞蛋的硬度就是i,問最壞情況下最少扔多少次雞蛋能得知硬度是多少
思路:對於每一幢大樓,有n層m個雞蛋,從第k層樓扔下雞蛋,如果碎了,那麼應該從k-1層一下開始扔,dp[k,m]=dp[k-1,m-1]。反之,如果沒碎,那就要從k+1層以上扔,那麼就是dp[i-k,m],i表示一共幾層樓,m表示有多少個雞蛋,k表示在這幢大樓裡是在第幾層扔下來的,因為要最壞情況,所以應該取max(dp[k-1,j-1],dp[i-k,j]),因為這一次扔也是一次,所以應該在加1,要取min(dp[i,j],max(dp[k-1,j-1],dp[i-k,j])+1),陣列要賦值為INF

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 1e9+5;
const int MAXN = 1e3+5;
const int MOD = 1e9+7;
const double eps = 1e-7;
int dp[1000+10][60];
int res()
{
    memset(dp,INF,sizeof(dp));
    for(int i=0;i<=50;i++)
        dp[0][i]=0;
    for(int i=1;i<=1000;i++)
    {
        for(int j=1;j<=50;j++)
        {
            for(int k=1;k<=i;k++)
            {
                dp[i][j]=min(dp[i][j],max(dp[i-k][j],dp[k-1][j-1])+1);
            }
        }
    }
}
int main()
{
    int t,num,n,m;
    ios::sync_with_stdio(false);
    res();
    cin>>t;
    while(t--)
    {
        cin>>num>>n>>m;
        cout<<num<<" "<<dp[m][n]<<endl;
    }
    return 0;
}

D - Running Median

4555 Running Median
For this problem, you will write a program that reads in a sequence of 32-bit signed integers. After
each odd-indexed value is read, output the median (middle value) of the elements received so far.
Input
The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets that
follow. The first line of each data set contains the data set number, followed by a space, followed by an
odd decimal integer M, (1 ≤ M ≤ 9999), giving the total number of signed integers to be processed.
The remaining line(s) in the dataset consists of the values, 10 per line, separated by a single space. The
last line in the dataset may contain less than 10 values.
Output
For each data set the first line of output contains the data set number, a single space and the number of
medians output (which should be one-half the number of input values plus one). The output medians
will be on the following lines, 10 per line separated by a single space. The last line may have less than
10 elements, but at least 1 element.
There should be no blank lines in the output.
Sample Input
3
1 9
1 2 3 4 5 6 7 8 9
2 9
9 8 7 6 5 4 3 2 1
3 23
23 41 13 22 -3 24 -31 -11 -8 -7
3 5 103 211 -311 -45 -67 -73 -81 -99
-33 24 56
Sample Output
1 5
1 2 3 4 5
2 5
9 8 7 6 5
3 12
23 23 22 22 13 3 5 5 3 -3
-7 -3
輸出每個奇數位數上的前面這些數的中位數,10個一換行,格式需要注意

#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
typedef long long LL;
using namespace std;
int t;
int n,m,a[10010],b[10010];
int main()
{
    cin>>t;
    while(t--)
    {
        int x=0;
        cin>>n>>m;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        for(int i=1; i<=m; i++)
        {
            cin>>a[i];
            if(i%2==1)
            {
                sort(a+1,a+i+1);
                b[++x]=a[i/2+1];
            }
        }
        cout<<n<<" "<<x<<endl;
        for(int i=1; i<=x; i++)
        {
            if(x>=10)
            {
                if(i%10==0)
                    cout<<b[i]<<endl;
                else
                {
                    if(i!=x)
                        cout<<b[i]<<" ";
                    else
                        cout<<b[i]<<endl;
                }
            }
            else
            {
                if(i!=x)
                {
                    cout<<b[i]<<" ";
                }
                else
                {
                    cout<<b[i]<<endl;
                }
            }
        }

    }
    return 0;
}

E - The Next Permutation

For this problem, you will write a program that takes a (possibly long) string of decimal digits, and
outputs the permutation of those decimal digits that has the next larger value (as a decimal number)
than the input number. For example:
123 -> 132
279134399742 -> 279134423799
It is possible that no permutation of the input digits has a larger value. For example, 987.
Input
The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets that
follow. Each data set is a single line that contains the data set number, followed by a space, followed
by up to 80 decimal digits which is the input value.
Output
For each data set there is one line of output. If there is no larger permutation of the input digits,
the output should be the data set number followed by a single space, followed by the string ‘BIGGEST’.
If there is a solution, the output should be the data set number, a single space and the next larger
permutation of the input digits.
Sample Input
3
1 123
2 279134399742
3 987
Sample Output
1 132
2 279134423799
3 BIGGEST

找出僅僅比這個數大的下一個數,如果沒有就輸出BIGGEST
沒有用過next_permutation這個函式,就硬生生的寫的
如果每一個數都小於等於前一個數,那麼就是BIGGEST,如果不是就從最後一個開始往前找,找到一個比後一個數小的數,就記錄下來位置,然後往後找那堆數裡比這個位置大的並且在那一堆裡最小的那個數交換她倆的位置,剩下的數從小到大排,依次輸出

#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
typedef long long LL;
using namespace std;
int b[1010];
int n,m;
int main()
{
   int t;
   char a[100],s[100],temp;
   cin>>t;
   while(t--)
   {
       int len,flag=0,x=0;
       scanf("%d %s",&n,a);
       len=strlen(a);
       for(int i=1;i<len;i++)
       {
           if(a[i]>a[i-1])
           {
               flag=1;
               break;
           }
       }
       if(flag==0)
       {
           cout<<n<<" "<<"BIGGEST"<<endl;
           continue;
       }
       for(int i=len-1;i>0;i--)
       {
           if(a[i-1]>=a[i])
           {
               continue;
           }
           else
           {
               int k=i-1;
               for(int j=len-1;j>=i;j--)
               {
                   if(a[k]<a[j])
                   {
                       temp=a[k];
                       a[k]=a[j];
                       a[j]=temp;
                       break;
                   }
               }
               for(int j=i;j<len;j++)
               {
                    b[++x]=a[j]-'0';
               }
               sort(b+1,b+x+1);
               int d=0;
               for(int j=i;j<len;j++)
               {
                   a[j]=b[++d]+'0';
               }
           }
           break;

       }
       cout<<n<<" "<<a<<endl;

   }
    return 0;
}

另一種就是賽後補得用STL裡的那個函式

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
char s[100];
char c[100];
int main()
{
    int t,n,flag;
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        flag=0;
        cin>>n>>s;
        strcpy(c,s);
        do
        {
            if(strcmp(s,c)>0)
            {
                printf("%d %s\n",n,s);
                flag=1;
                break;
            }

        }while(next_permutation(s,s+strlen(s)));
        if(flag==0)
            printf("%d BIGGEST\n",n);
    }

    return 0;
}

動態規劃:

F 4557 Adjacent Bit Counts

For a string of n bits x1, x2, x3,…, xn, the adjacent bit count of the string (AdjBC(x)) is given by
x1 ∗ x2 + x2 ∗ x3 + x3 ∗ x4 + . . . + xn−1 ∗ xn
which counts the number of times a 1 bit is adjacent to another 1 bit. For example:
AdjBC(011101101) = 3
AdjBC(111101101) = 4
AdjBC(010101010) = 0
Write a program which takes as input integers n and k and returns the number of bit strings x of n
bits (out of 2
n
) that satisfy AdjBC(x) = k. For example, for 5 bit strings, there are 6 ways of getting
AdjBC(x) = 2:
11100, 01110, 00111, 10111, 11101, 11011
Input
The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets that
follow. Each data set is a single line that contains the data set number, followed by a space, followed by
a decimal integer giving the number (n) of bits in the bit strings, followed by a single space, followed by
a decimal integer (k) giving the desired adjacent bit count. The number of bits (n) will not be greater
than 100 and the parameters n and k will be chosen so that the result will fit in a signed 32-bit integer.
Output
For each data set there is one line of output. It contains the data set number followed by a single space,
followed by the number of n-bit strings with adjacent bit count equal to k.
Sample Input
10
1 5 2
2 20 8
3 30 17
4 40 24
5 50 37
6 60 52
7 70 59
8 80 73
9 90 84
10 100 90
Sample Output
1 6
2 63426
3 1861225
4 168212501
5 44874764
6 160916
7 22937308
8 99167
9 15476
10 23076518
題意:一共有n個數,每一位只能是0或者1,權值是k,計算權值的方法是x1 ∗ x2 + x2 ∗ x3 + x3 ∗ x4 + . . . + xn−1 ∗ xn,要想滿足這個條件有多少種方式
可以用三維陣列來表示,dp[i,j,k] i表示一共有i位數,j表示權值,k表示末位的數是0還是1,那麼,dp[i,j,0]=dp[i-1,j,0]+dp[i-1,j,1]
dp[i,j,1]=dp[i-1,j-1,1]+dp[i-1,j,0]
初始化n個數構成權值為0的時候只需dp[i,0,0]=dp[i-1,0,1]+dp[i-1,0,0]
dp[i,0,1]=dp[i-1,0,0]
dp[i,j,1]=dp[i-1,j-1,1]+dp[i-1,j,0]這個是如何想到的呢?首先我們考慮的是在權值為j並且值為1的情況下,我們應該考慮的是要使權值不變,我們必須先考慮的是前一位必須是0,如果是1的話我們應該考慮的是權值為j-1的情況

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 1e9+5;
const int MAXN = 1e3+5;
const int MOD = 1e9+7;
const double eps = 1e-7;
int dp[110][110][3];
int res()
{
    dp[1][0][0]=dp[1][0][1]=1;
    for(int i=2;i<=100;i++)
    {
        dp[i][0][0]=dp[i-1][0][0]+dp[i-1][0][1];
        dp[i][0][1]=dp[i-1][0][0];
        for(int j=1;j<i;j++)
        {
           dp[i][j][1]=dp[i-1][j][0]+dp[i-1][j-1][1];
           dp[i][j][0]=dp[i-1][j][0]+dp[i-1][j][1];
        }
    }
}
int main()
{
    int t,num,n,k;
    ios::sync_with_stdio(false);
    cin>>t;
    res();
    while(t--)
    {
        cin>>num>>n>>k;
        cout<<num<<" "<<dp[n][k][0]+dp[n][k][1]<<endl;
    }
    return 0;
}