2018-非新生

A. Fire Net

Problem Description
Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall.

A blockhouse is a small castle that has four openings through which to shoot. The four openings are facing North, East, South, and West, respectively. There will be one machine gun shooting through each opening.

Here we assume that a bullet is so powerful that it can run across any distance and destroy a blockhouse on its way. On the other hand, a wall is so strongly built that can stop the bullets.

The goal is to place as many blockhouses in a city as possible so that no two can destroy each other. A configuration of blockhouses is legal provided that no two blockhouses are on the same horizontal row or vertical column in a map unless there is at least one wall separating them. In this problem we will consider small square cities (at most 4x4) that contain walls through which bullets cannot run through.

The following image shows five pictures of the same board. The first picture is the empty board, the second and third pictures show legal configurations, and the fourth and fifth pictures show illegal configurations. For this board, the maximum number of blockhouses in a legal configuration is 5; the second picture shows one way to do it, but there are several other ways.

Your task is to write a program that, given a description of a map, calculates the maximum number of blockhouses that can be placed in the city in a legal configuration.

Input
The input file contains one or more map descriptions, followed by a line containing the number 0 that signals the end of the file. Each map description begins with a line containing a positive integer n that is the size of the city; n will be at most 4. The next n lines each describe one row of the map, with a ‘.’ indicating an open space and an uppercase ‘X’ indicating a wall. There are no spaces in the input file.
Output
For each test case, output one line containing the maximum number of blockhouses that can be placed in the city in a legal configuration.
Sample Input
4
.X..
….
XX..
….
2
XX
.X
3
.X.
X.X
.X.
3

.XX
.XX
4
….
….
….
….
0

Sample Output
5
1
5
2
4

题意:
此题大意是在一个最大4*4网格组成的城市里,每个网格可能为“墙壁”(用‘X’表示)和“街道”(用‘.’表示)。现在在街道放置碉堡,每个碉堡可以向上下左右四个方向开火,子弹射程无限远。墙壁可以阻挡子弹。问最多能放置多少个碉堡,使它们彼此不会互相摧毁。

# include <stdio.h>
# include <string.h>


char g[4][4] ;
int vis[4][4] ;
int n, ans ;
int tab[4][2] = {0,1,0,-1,1,0,-1,0} ;


void dfs(int pos, int num)
{
    int x = pos/n, y = pos%n ;
    int xx, yy, i, j ;
    int buff[4][4] ;
//    if(pos==n*n) return ;
    if (g[x][y]=='X')return ;
    if (vis[x][y]==1) return ;

    for(i=0;i<n;i++)for(j=0;j<n;j++)buff[i][j]=vis[i][j];
    vis[x][y]=1;
    for(i=0;i<4;i++)
    {
        for(xx=x+tab[i][0],yy=y+tab[i][1] ;
            xx>=0&&xx<n&&yy>=0&&yy<n&&g[xx][yy]=='.';
            xx+=tab[i][0],yy+=tab[i][1])
            vis[xx][yy]=1 ;
    }
    if(num+1>ans)ans=num+1;
    for(i=pos+1;i<n*n;i++)dfs(i,num+1);
    for(i=0;i<n;i++)for(j=0;j<n;j++)vis[i][j]=buff[i][j];
}


int main ()
{
    int i ;
    while (~scanf("%d",&n)&&n)
    {
        for(i=0;i<n;i++) 
        scanf("%s",g[i]) ;
        memset(vis,0,sizeof(vis)) ;
        ans=0;
        for(i=0;i<n*n;i++)dfs(i,0) ;
        printf("%d\n", ans) ;
    }
    return 0 ;
}

B. Ball
第2319 题
Problem Description
N ladies attend the ball in the King’s palace. Every lady can be described with three values: beauty, intellect and richness. King’s Master of Ceremonies knows that ladies are very special creatures. If some lady understands that there is other lady at the ball which is more beautiful, smarter and more rich, she can jump out of the window. He knows values of all ladies and wants to find out how many probable self-murderers will be on the ball. Lets denote beauty of the ii -th lady by Bi , her intellect by Ii and her richness by Ri . Then ii -th lady is a probable self-murderer if there is some j -th lady that B[i]

#include<iostream>  
#include<cstdlib>  
#include<stdio.h>  
#include<map>  
#include<algorithm>  
using namespace std;  
const int maxn=500005;  
const int minn=1000000000;  
struct Node  
{  
    int b,l,r;  
    bool operator <(const Node &node) const  
    {  
        return b!=node.b?b<node.b:l!=node.l?l>node.l:r<node.r;  
    }  
}q[maxn];  
int main()  
{  
    int n;  
    map<int,int>qiqi;  
    map<int,int>::iterator it;  
    while(scanf("%d",&n)!=EOF)  
    {  
        for(int i=0;i<n;i++) 
            scanf("%d",&q[i].b);  
        for(int i=0;i<n;i++) 
            scanf("%d",&q[i].l);  
        for(int i=0;i<n;i++) 
            scanf("%d",&q[i].r);  
        sort(q,q+n);  
        int count=0;  
        qiqi.clear();  
        qiqi[minn]=-minn;qiqi[-minn]=minn;  
        for(int i=n-1;i>=0;i--)  
        {  
            it=qiqi.upper_bound(q[i].l);
            if(it->second>q[i].r) 
                count++;
            else if(qiqi[q[i].l]<q[i].r)
            {  
                qiqi[q[i].l]=q[i].r;  
                for(it=--qiqi.lower_bound(q[i].l);it->second<q[i].r;)  
                {  
                    qiqi.erase(it--);  
                }  
            }  
        }  
        cout<<count<<endl;  

    }  
}

C. Lizards and Basements 2

Problem Description
This is simplified version of the problem used on the original contest. The original problem seems to have too difiicult solution. The constraints for input data have been reduced.
Polycarp likes to play computer role-playing game «Lizards and Basements». At the moment he is playing it as a magician. At one of the last levels he has to fight the line of archers. The only spell with which he can damage them is a fire ball. If Polycarp hits the i-th archer with his fire ball (they are numbered from left to right), the archer loses a health points. At the same time the spell damages the archers adjacent to the i -th (if any) — they lose b ( 1<=b

#include<stdio.h>
#include<iostream>
#include<vector>
using namespace std;
#define N 110
#define ll int

ll n, a, b;
ll h[N];
vector<int>G,ans;
void dfs(int u, bool hehe)
{//hehe=true表示u-1没死
    if(u==n && hehe==false)
    {
        if(G.size()<ans.size())
            ans = G;
        return ;
    }
    int siz = 0;
    if(hehe) 
    {
        while(h[u-1]>0)siz++,h[u-1]-=b, h[u]-=a, h[u+1]-=b, G.push_back(u);
    }
    if(h[u]>0) 
    {
        while(h[u]>0) 
        {
            dfs(u+1,true);
            h[u-1]-=b;
            h[u]-=a;
            h[u+1]-=b;
            siz++;
            G.push_back(u);
        }
    }
    dfs(u+1,false);
    h[u]+=a*siz;
    h[u+1]+=b*siz;
    h[u-1]+=b*siz;
    while(siz--)G.erase(G.end()-1);
}
int main(){
    ll i, j;
    scanf("%d %d %d",&n,&a,&b); 
    G.clear(); ans.clear();
    for(i=1;i<=n;i++)
        scanf("%d",&h[i]), h[i]++;
    while(h[1]>0){
        h[2] -= a;
        h[1] -= b;
        h[3] -= b;
        ans.push_back(2);
    }
    while(h[n]>0){
        h[n-2] -= b;
        h[n-1] -= a;
        h[n] -= b;
        ans.push_back(n-1);
    }
    G = ans;
    for(i=1;i<=100;i++)ans.push_back(i);
    dfs(2,false);
    printf("%d\n",ans.size());
    for(i = 0; i < ans.size(); i++)printf("%d%c",ans[i],i==ans.size()-1?'\n':' ');

    return 0;
}

D. Numbers

Problem Description
Little Petya likes numbers a lot. He found that number 123 in base 16 consists of two digits: the first is 7 and the second is 11. So the sum of digits of 123 in base 16 is equal to 18.
Now he wonders what is an average value of sum of digits of the number A written in all bases from 2 to A−1 .
Note that all computations should be done in base 10. You should find the result as an irreducible fraction, written in base 10.
Input
Input contains one integer number A ( 3<=A<=1000).
Output
Output should contain required average value in format «X/Y», where X is the numerator and Y is the denominator.
Sample Input
5
Sample Output
7/3

题意:
给出一整数n,计算用2~n-1进制表示n时,每一个进制下所有位上的数字的和的平均数(结果用分数表示)

#include <iostream>
using namespace std;
long long GetGreatestCommonDivision(long long iNum1, long long iNum2)
{ //辗转相除法求最大公约数
    if (iNum2 == 0)
        return iNum1;
    else
        return GetGreatestCommonDivision(iNum2, iNum1%iNum2);
}
int main()
{
    long long iNum, i, iTemp, iSum = 0,iGCD; //iNum-输入的数;i-循环计数器;iTemp-进制转换时的临时变量;iSum-累加器;iGCD-存放iSum和iNum-2的最大公约数
    cin >> iNum; //读入数
    for (i = 2; i <= iNum - 1; ++i)
    { //模拟一遍从2到iNum-1进制的转换
        iTemp = iNum; //将iTemp恢复到iNum
        while (iTemp != 0)
        { //开始进制转换,iTemp=0时终止循环
            iSum += iTemp%i; //计算一位数并累加
            iTemp /= i; //除去进制数
        }
    }
    iNum -= 2; //从2到iNum-1共有iNum-2种进制,故减去2
    iGCD = GetGreatestCommonDivision(iSum, iNum); //计算iSum和iNum-2的最大公约数
    iSum /= iGCD; //约分分子
    iNum /= iGCD; //约分分母
    cout << iSum << '/' << iNum<<endl; //输出分数
    return 0; //结束
}

E. Queue
第2322 题
Problem Description
On a cold winter evening our hero Vasya stood in a railway queue to buy a ticket for Codeforces championship final. As it usually happens, the cashier said he was going to be away for 5 minutes and left for an hour. Then Vasya, not to get bored, started to analyze such a mechanism as a queue. The findings astonished Vasya.
Every man is characterized by two numbers:ai​ , which is the importance of his current task (the greater the number is, the more important the task is) and number ci​ , which is a picture of his conscience. Numbers ai​ form the permutation of numbers from 1 to n .
Let the queue consist of n−1 people at the moment. Let’s look at the way the person who came number nn behaves. First, he stands at the end of the queue and the does the following: if importance of the task ai​ of the man in front of him is less than an​ , they swap their places (it looks like this: the man number nn asks the one before him: “Erm… Excuse me please but it’s very important for me… could you please let me move up the queue?”), then he again poses the question to the man in front of him and so on. But in case when ai​ is greater than an​ , moving up the queue stops. However, the man number n can perform the operation no more than cn​ times.
In our task let us suppose that by the moment when the man number nn joins the queue, the process of swaps between n-1 will have stopped. If the swap is possible itnecessarily takes place.
Your task is to help Vasya model the described process and find the order in which the people will stand in queue when all the swaps stops.
Input
The first input line contains an integer nn which is the number of people who has joined the queue ( 1<=n<=10^5 ). In the next nn lines descriptions of the people are given in order of their coming — space-separated integers ai​ and ci​ ( 1<=ai​<=n , 0<=ci​<=n ). Every description is located on s single line. All the ai​ ‘s are different.

Output
Output the permutation of numbers from 1 to n , which signifies the queue formed according to the above described rules, starting from the beginning to the end. In this succession the i-th number stands for the number of a person who will stand in line on the place number ii after the swaps ends. People are numbered starting with 1 in the order in which they were given in the input. Separate numbers by a space.
Sample Input
2
1 0
2 1
Sample Output
2 1

题意:
有n个人依次排队,每个人都有两个属性值 a[i] 、c[i] ,a[i]是重要性值,数值越大越重要,c[i]是良心值。假如前i-1人已经排好队后,第i个人来排队,初始时他在队尾,如果他的a[i]大于排在他前面那位的重要性值,那么两人可以交换位置,每次交换良心值减1,直到他前面的人的重要性值大于a[i]或者良心值为0的时候(即最多交换c[i]次),问最终n个人的队列次序。

解题思路:
每个人i换到的位置有两种可能,第一种也就是队伍中从后往前第一个比他的重要度大,第二种就是按位置来说的i-ci。在这两种中找到一个靠后的。可以用Splay维护,每个节点记录a[i],还有子树中a[i]的最大值。
每次找下标,可以二分下标,然后在Splay中找到这个节点,然后把这个节点Splay到根,返回a[i]的最大值。
再把当前节点插入进去。

#include<stdio.h>
#define inf 1000000000
int v[100010],mx[100010],ch[100010][2],fa[100010],id[100010],siz[100010],rt,tot;
int max(int a,int b){return a>b?a:b;}
void pushup(int x)
{
    siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
    mx[x]=max(v[x],max(mx[ch[x][0]],mx[ch[x][1]]));
}
void rot(int x)
{
    int y,z,f,B;
    y=fa[x];
    z=fa[y];
    if(y==rt)rt=x;
    f=ch[y][0]==x;
    B=ch[x][f];
    fa[x]=z;
    fa[y]=x;
    if(B)fa[B]=y;
    ch[x][f]=y;
    ch[y][f^1]=B;
    if(ch[z][0]==y)ch[z][0]=x;
    if(ch[z][1]==y)ch[z][1]=x;
    pushup(y);
    pushup(x);
}
void splay(int x,int gl)
{
    int y,z;
    while(fa[x]!=gl)
    {
        y=fa[x];
        z=fa[y];
        if(z!=gl)rot((ch[y][0]==x&&ch[z][0]==y)||(ch[y][1]==x&&ch[z][1]==y)?y:x);
        rot(x);
    }
}
int res;
void getrp(int x,int val)
{
    if(x==0)
    return;
    if(mx[ch[x][1]]>val)
    return getrp(ch[x][1],val);
    if(v[x]>val)
    {
        res=x;
        return;
    }
    getrp(ch[x][0],val);
}
int getkth(int x,int k)
{
    if(k<=siz[ch[x][0]])
    return getkth(ch[x][0],k);
    if(k>siz[ch[x][0]]+1)
    return getkth(ch[x][1],k-siz[ch[x][0]]-1);
    return x;
}
void dfs(int x)
{
    if(ch[x][0])dfs(ch[x][0]);
    printf("%d ",id[x]);
    if(ch[x][1])dfs(ch[x][1]);
}
int main()
{
    int n,i,a,b;
    scanf("%d%d%d",&n,v+1,&b);
    mx[0]=-inf;
    id[1]=1;
    tot=1;
    rt=1;
    mx[1]=v[1];
    siz[1]=1;
    for(i=2;i<=n;i++)
    {
        scanf("%d%d",&a,&b);
        tot++;
        id[tot]=i;
        mx[tot]=v[tot]=a;
        siz[tot]=1;
        res=0;
        getrp(rt,a);
        if(res==0)
        {
            if(b>=tot-1)
            {
                splay(getkth(rt,1),0);
                ch[rt][0]=tot;
                fa[tot]=rt;
            }
            else
            {
                splay(getkth(rt,tot-1-b),0);
                if(ch[rt][1]==0)
                {
                    ch[rt][1]=tot;
                    fa[tot]=rt;
                }
                else
                {
                    splay(getkth(rt,tot-b),rt);
                    ch[ch[rt][1]][0]=tot;
                    fa[tot]=ch[rt][1];
                    pushup(ch[rt][1]);
                }
            }
        }
        else
        {
            splay(res,0);
            if(ch[rt][1]==0)
            {
                ch[rt][1]=tot;
                fa[tot]=rt;
            }
            else
            {
                if(b>=siz[ch[rt][1]])
                {
                    splay(getkth(rt,siz[ch[rt][0]]+2),rt);
                    ch[ch[rt][1]][0]=tot;
                    fa[tot]=ch[rt][1];
                    pushup(ch[rt][1]);
                }
                else
                {
                    splay(getkth(rt,tot-1-b),0);
                    if(ch[rt][1]==0)
                    {
                        ch[rt][1]=tot;
                        fa[tot]=rt;
                    }
                    else
                    {
                        splay(getkth(rt,tot-b),rt);
                        ch[ch[rt][1]][0]=tot;
                        fa[tot]=ch[rt][1];
                        pushup(ch[rt][1]);
                    }
                }
            }
        }
        pushup(rt);
    }
    dfs(rt);
}

F. Industrial Nim

Problem Description
There are nn stone quarries in Petrograd.
Each quarry owns mi​ dumpers ( 1<=i<=n ). It is known that the first dumper of the i -th quarry has xi​ stones in it, the second dumper has xi +1 stones in it, the third has xi​ +2 , and the mi​ -th dumper (the last for the i -th quarry) has xi​+mi ​−1 stones in it.
Two oligarchs play a well-known game Nim. Players take turns removing stones from dumpers. On each turn, a player can select any dumper and remove any non-zero amount of stones from it. The player who cannot take a stone loses.
Your task is to find out which oligarch will win, provided that both of them play optimally. The oligarchs asked you not to reveal their names. So, let’s call the one who takes the first stone «tolik» and the other one «bolik».

Input
The first line of the input contains one integer number n ( 1<=n<=10^5 ) — the amount of quarries. Then there follow n lines, each of them contains two space-separated integers xi​ and mi​ ( 1<=xi​,mi​<=10^16 ) — the amount of stones in the first dumper of the i -th quarry and the number of dumpers at the i -th quarry.
Output
Output «tolik» if the oligarch who takes a stone first wins, and «bolik» otherwise.
Sample Input
2
2 1
3 2
Sample Output
Tolik

题意:
第一行给出N表示有N个采石场,接下来N行每一行一个Mi一个Xi,表示第i个采石场有Mi辆车,这个采石场中第1辆车的石头数量是Xi,第2辆车中有Xi+1个石头……第Mi辆车的石头的数量是Xi+Mi-1。 有两个人每次从任意一辆车中取任意数量的石头(不能为0),最后一个取完所有石头的赢。 若先手赢输出”tolik”,后手赢输出”bolik”。

解题思路:
关于nim博弈:是两个人在若干堆中轮流取石子,每次每人可以选择一堆,从中取出最少数量为1个,最多为一堆的石子,先手取完胜。
如果只有一堆,那么就先手直接取完一堆,先手胜。
如果两堆,那么主要看这两堆石子是否数量相同,若最初不相同,则先手可以将其取至相同状态,不论后手取多少,先手都可以在另一堆取相同数量,然后维持到游戏结束,否则后手可以维持这个平衡状态,一直到取最后一次。
所以在有很多堆时,就可以通过看他们所有堆的二进制的相对位上的和是否是偶数,若都是偶数,那就是达到了平衡态,否则可以将非平衡态的非平衡二进制数位上拿走1,使他再次达到平衡态。
所以若堆上的相对数位和为偶数,那么他们这一位进行连续异或运算得出来的答案为0,所以若达到平衡态,则所有数位进行异或结果都是0。
这里用到了一个性质:一个偶数和它的下一个奇数的异或和为1。于是对于每段连续自然数只需要特判一下头尾即可,就能知道其异或和。最后异或和非零则先手必胜。

#include<iostream>
#include<stdio.h>


using namespace std;

int n;
long long ans;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    {
        long long a,len;
        scanf("%lld%lld",&a,&len);
        if(a%2)
        {
            ans^=a,++a,--len;
        }
        if(len&&len%2)
        {
            ans^=a+len-1,--len;
        }
        if(len&&(len/2)%2)
            ans^=1;
    }
    if(ans)
        printf("tolik\n");
    else 
        printf("bolik\n");
    return 0;
}

G. Line

Problem Description
A line on the plane is described by an equation Ax+By+C=0 . You are to find any point on this line, whose coordinates are integer numbers from −5⋅10^18 to 5·10^18 inclusive, or to find out that such points do not exist.
Input
The first line contains three integers A , B and C ( -2⋅10^9<=A,B,C<=2⋅10^9 ) — corresponding coefficients of the line equation. It is guaranteed that A^2+B^2>0 .
Output
If the required point exists, output its coordinates, otherwise output -1.
Sample Input
2 5 3
Sample Output
6 -3

题意:
一条直线:Ax+By+C=0(AB不同时为0),找到任意一个点(在-5e18~5e18之间)让它的横纵坐标均为整数,或者确定没有这样的点。

解题思路:
一道扩欧的模板题

#include<iostream>
#include<cstdio>
using namespace std;
long long kuoou(long long a,long long b,long long &x1,long long &y1)
{
    long long x2,y2;
    if(b==0)
    {
        x1=1;
        y1=0;
        return a;
    }
    long long d=kuoou(b,a%b,x2,y2);
    x1=y2;
    y1=x2-a/b*y2;
    return d;
}
int main()
{
    long long a,b,c,x,y;
    scanf("%lld%lld%lld",&a,&b,&c);
    c=-c;
    long long d=kuoou(a,b,x,y);//这里面的x,y只是当ax+by==gcd(a,b)时候的解,还要在下面进行转换
    if(c%d!=0)
    {
        printf("-1");
        return 0;
    }
    x=x*c/d;
    y=y*c/d;
    printf("%lld %lld\n",x,y);
    return 0;
}

H. Bindian Signalizing

Problem Description
Everyone knows that long ago on the territory of present-day Berland there lived Bindian tribes. Their capital was surrounded by nn hills, forming a circle. On each hill there was a watchman, who watched the neighbourhood day and night.
In case of any danger the watchman could make a fire on the hill. One watchman could see the signal of another watchman, if on the circle arc connecting the two hills there was no hill higher than any of the two. As for any two hills there are two different circle arcs connecting them, the signal was seen if the above mentioned condition was satisfied on at least one of the arcs. For example, for any two neighbouring watchmen it is true that the signal of one will be seen by the other.
An important characteristics of this watch system was the amount of pairs of watchmen able to see each other’s signals. You are to find this amount by the given heights of the hills.

Input
The first line of the input data contains an integer number n ( 3<=n<=10^6 ), n — the amount of hills around the capital. The second line contains n numbers — heights of the hills in clockwise order. All height numbers are integer and lie between 1 and 10^9 .
Output
Print the required amount of pairs.
Sample Input
5
1 2 4 5 3
Sample Output
7

题意:
大家都知道,很久以前在今境内Bindian部落居住在贝尔兰。他们的首都四面环绕着N座小山,形成了一个圈。每座山上都有一个守夜人,日夜守护着这个街区。
万一有危险,守夜人就可以在山上点火。一个看守人可以看到另一个看守人的信号,如果在两个山头上连着一个圆弧,就没有比这两个山头高的山了。对于任何两个山丘,有两个不同的圆弧连接它们,如果在至少一个弧上满足上述条件,信号就会被看到。例如,任何两个相邻的人真是一个会被其他看到的信号。
这系统的一个重要特点是守望者能够看到对方的信号对量。你要在山的高度找到这个数量。

解题思路:
先把这个环变成一条链,把最高的山作为第一个山,按照顺序复制序列,再在最后接上一个最高的山。
设left[i]表示i左边第一个比i高的位置,right[i]表示i右边第一个比i高的位置,count[i]表示在i到right[i]的左开右闭区间内高度等于i的山的数目,那么每座山能看到的山的组数至少有count[i]组和(i,l[i])与(i,r[i])这两组,不过当l[x]=0且r[x]=n时其实是一组,注意判断。
于是问题就变成了求left数组、right数组和count数组,可以通过动态规划的思想来做。

#include <iostream>
#include<cstdio>

using namespace std;
int t[1000002],h[1000002],l[1000002],r[1000002],cnt[1000002];
int main() 
{
    int n,p=0;
    long long ans=0;
    scanf("%d",&n);
    for(int i=0;i<n;++i)
        scanf("%d",t+i);
    for(int i=1;i<n;++i)
        if(t[i]>t[p])            //寻找最大值
            p=i;
    for(int i=0;i<=n;++i)
        h[i]=t[(i+p)%n];        //转环为链
    for(int i=1;i<=n;++i) 
    {
        l[i]=i-1;                   //初始化为i左边第一个
        while(l[i]&&h[i]>=h[l[i]])
            l[i]=l[l[i]];           //满足条件便递推
    }
    for(int i=n-1;i>=0;--i) 
    {
        r[i]=i+1;                       //初始化为i右边第一个
        while(r[i]<n&&h[i]>h[r[i]])
            r[i]=r[r[i]];               //满足条件便递推
        if(r[i]<n&&h[i]==h[r[i]]) 
        {
            cnt[i]=cnt[r[i]]+1;         //递推count数组
            r[i]=r[r[i]];
        }
    }
    for(int i=0;i<n;++i) 
    {
        ans+=cnt[i];            //至少能看到的组数
        if(h[i]<h[0]) 
        {
            ans+=2;             //另外的两组
            if(!l[i]&&r[i]==n)
                ans--;          //特判是同一组的情况
        }
    }
    printf("%lld\n",ans);
    return 0;
}

J. Equal Sum Partitions

Problem Description
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>  
using namespace std;  
const int maxN=10024;  
int a[maxN],n;  

int test(int mid)  
{  
    int i,sum=0;  
    for(i=1;i<=n;++i)
    {  
        sum+=a[i];  
        if(sum==mid)  
            sum=0;  
        else  if(sum<mid)  
            continue;  
        else  
            return 0;  
    }  
    if(sum!=0)  
        return 0;  
    return 1;  
}  

int main()  
{  
    int cases,cases_num,ans;  
    scanf("%d",&cases);  
    while(cases--)
    {  
        int i,sum=0;  
        scanf("%d%d",&cases_num,&n);          
        for(i=1;i<=n;++i)
        {  
            scanf("%d",&a[i]);  
            sum+=a[i];  
        }  
        for(i=0;i<=sum;++i)  
            if(test(i)==1)
            {  
                ans=i;  
                break;  
            }  
        printf("%d %d\n",cases_num,ans);  
    }  
    return 0;     
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值