Preliminaries for Benelux Algorithm Programming Contest 2019 计蒜客解(补)题报告

A - Architecture(思维)

题目链接

Your brother has won an award at the recent Breakthroughs in Architectural Problems Conference and has been given the once in a lifetime opportunity of redesigning the city center of his favorite city Nijmegen. Since the most striking parts of a city’s layout are the skylines, your brother has started by drawing ideas for how he wants the northern and eastern skylines of Nijmegen to look. However, some of his proposals look rather outlandish, and you are starting to wonder whether his designs are possible. For his design, your brother has put an R × C grid on the city. Each cell of the city will contain a building of a certain height. The eastern skyline is given by the tallest building in each of the R rows, and the northern skyline is given by the tallest building in each of the C columns. A pair of your brother’s drawings of skylines is possible if and only if there exists some way of assigning building heights to the grid cells such that the resulting skylines match these drawings. Figure A.1 shows a possible city with the northern and eastern skylines exactly as given in the input of the first sample.
在这里插入图片描述
Input
• The first line consists of two integers 1≤ R,C ≤100, the number of rows and columns in the grid.
• ThesecondlineconsistsofRintegersx1,…,xR describingtheeasternskyline(0≤ xi ≤1000 for all i).
• ThethirdlineconsistsofC integersy1,…,yC describingthenorthernskyline(0≤ yj ≤1000 for all j).

Output
one line containing the string possible if there exists a city design that produces the specified skyline, and impossible otherwise.
在这里插入图片描述
在这里插入图片描述
1.题目大意:第一行给出r行每行的最大值,第二行给出c列每列的最大值,判断是否存在冲突

2.比赛时有点糊涂,本以为判断最值就行了,但被自己又否定了。无奈想出一种玄学做法:先将r行每个数都设置为该行的最大值,接着输入列最大时将该列大于它的都改为列最大,接着再判断每一行的最大值是否被改变。但是交了一次WA了。没想出来实例,但是觉得进行上面一次这样的测验貌似不行,那就两次!第二次交换对象,先把每一列都设置为该列最大值,接着改变行,最后验证列。然后就过了

3.正解:从所有的行最值里找出最大的,从所有列最小中求出列最大的。如果这两个相等那么就满足条件,否则存在冲突。证明:由于每一个小格既能代表行又能代表列,那么将两个相等的最值放在所有行最大值所在行和所有列最大值所在列相交的小格里,对于其他的行最值,都放在列最大值所在列;对于其他的列最值,都放着行最大值所在行。那么就不会互相影响,否则就会产生冲突

#include <iostream>
#include <algorithm>
using namespace std;
 
int n, m;
int a[105], b[105];
 
int main()
{
	scanf("%d %d", &n, &m);
	int mxl = -1, mxr = -1;
	for (int i = 1; i <= n; i++) scanf("%d", &a[i]), mxl = max(mxl, a[i]);
	for (int i = 1; i <= m; i++) scanf("%d", &b[i]), mxr = max(mxr, b[i]);
	if(mxl == mxr) printf("possible\n");
	else printf("impossible\n");
 
	return 0;
}
B - Bracket Sequence(手写栈求解括号表达式)

传送门

C - Canyon Crossing(二分答案+BFS)

题目链接

TheBridgeAndPassagewayCreatorsareresponsibleformakingnewpathsthroughthelocal mountains. They have approved your plan to build anewr oute through your favorite canyon. You feverishly start working on this beautiful new path, when you realize you failed to take into account the flow of a nearby river: the canyon is flooded! Apparently this happens once every blue moon, making some parts of the path inaccessible. Because of this, you want to build a path such that the lowest point on the path is as high as possible. You quickly return to the village and use all of your money to buy rope bridges. You plan to use these to circumvent the lowest parts of the canyon.Your map of the canyon consists of arectangular grid of cells,each containing a number giving the height of the terrain at that cell. The path will go from the south side of the canyon (bottom on your map) to the north side (top of your map), moving through a connected sequence of cells. Two cells are considered connected if and only if they share an edge. In particular, two diagonally touching cells are not considered to be connected. This means that for any cell not on the edge of the map, there are 4 other cells connected to it. The left of figure C.1 contains the map for the first sample input.The path through the canyon can start on any of the bottom cells of the grid, and end on any of the cells in the top tow, like the two paths on the right in C.1. The lowest height is given by the lowest height of any of the cells the paths goes through. Each bridge can be used to cross exactly one cell. This cell is then not taken into account when calculating the minimal height of the path. Note that is allowed to chain multiple bridges to use them to cross multiple cells,Given the map of the canyon and the number of bridges available, find the lowest height of an optimal path.
在这里插入图片描述
Input
• A single line containing three integers: 1≤ R ≤1000 and 1≤ C ≤1000, the size of the map, and 0≤ K ≤ R−1, the number of bridges you can build.
• This is followed by R lines each containing C integers. The j-th integer on the i-th line corresponds to the height 0 ≤ Hi,j ≤ 109 of the canyon at point (i,j). The first line corresponds to the northern edge of the canyon, the last line to the southern edge.

Output
Output a single integer, the lowest height of the optimal path.
在这里插入图片描述
题目大意:给出一个有权的r行c列的棋盘图,如今要从最后一行走到第一行,在最多建k座桥(在某一节点建桥后该点的权值失效)的情况下,求出所走路径下最小的最大值

传送门

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
typedef pair<int,int> P;
const int maxn=1005;
int G[maxn][maxn];
bool vis[maxn][maxn];
int dx[]={1,-1,0,0},dy[]={0,0,1,-1};
int r,c,k;

bool bfs(int val){
    memset(vis,0,sizeof vis);
    queue<P> q[k+2];
    for(int i=1;i<=c;i++){
        vis[r][i]=1;
        q[G[r][i]<val?1:0].push(make_pair(r,i)); //貌似初始放在0和1两个队列中
    }
    for(int i=0;i<=k;i++){
        //cout<<q[i].size()<<endl;
        while(q[i].size()){
            P u=q[i].front();
            if(u.first==1) return 1;
            q[i].pop();
            for(int j=0;j<4;j++){
                int x=u.first+dx[j];
                int y=u.second+dy[j];
                if(x<1 || x>=r || y<1 || y>c) continue;
                if(!vis[x][y]){
                    vis[x][y]=1;
                    q[G[x][y]<val?i+1:i].push(make_pair(x,y));
                }
            }
        }
    }
    return 0;

}

int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>r>>c>>k;
    int L=0,R=0,mid;
    for(int i=1;i<=r;i++)
    for(int j=1;j<=c;j++){
        cin>>G[i][j];
        R=max(R,G[i][j]);
    }
    int ans=L;
    for(int i=1;i<=100;i++){
        mid=(L+R)>>1;
        if(bfs(mid)){
            ans=mid;
            L=mid+1;
        }else R=mid-1;
    }
    cout<<ans<<endl;
    return 0;
}

F - Floor Plan(打表找规律)

题目链接

You are an architect and you have just been appointed to build a new swimming hall. The organisation behind these plans has acquired funding for a swimming pool and surrounding building as large asthey want, butunfortunately they could not find anyone willing to pay for the floor surrounding the pool. They decided to pay for the floor tiles out of their own pocket. Because this has already cost them an arm and a leg, they want you to use all the floor tiles in your proposed plan. Being an architect, you care for aesthetics. You see it as absolutely vital that both the swimming pool and the surrounding building are perfect squares. This raises an interesting problem: how can you make sure that the square shapes are guaranteed, while still using all the floor tiles the organisation bought? Given the number of tiles n, find the length of the side of the building m and and the length of the side of the pool k such that n = m2−k2, or print impossible if no suitable m and k exist.

Input
• One line containing a single integer 1≤ n ≤109.

Output
Print two non-negative integers m, k such that n = m2−k2, or print impossible if no such integers exist. If there are multiple valid solutions, you may output any one of them.
在这里插入图片描述
1.题目大意:给出一个数n,如果存在两个数m和k满足n=m2-k2,则输出m和k,否则输出不可能

2.打表找规律。对前二十项打表,可以发现这样一个规律:对于任意奇数一定存在m和k,且一定有一组m=(n+1)/2和k=(n+1)/2-1;对于偶数,当且仅当n%4==0一定存在m和k,且一定有一组m=n/4+1和k=n/4-1,否则不存在

#include <iostream>

using namespace std;
const int maxn=1e9+10;
typedef long long ll;

int main()
{
    int n;
    cin>>n;
    if(n&1){
        cout<<(n+1)/2<<" "<<(n+1)/2-1;
    }else{
        if(n%4==0){
            cout<<n/4+1<<" "<<n/4-1;
        }else{
            cout<<"impossible";
        }
    }

    return 0;
}

G - Greetings! (签到)

题目链接

Now that Snapchat and Slingshot are soooo 2018, the teenagers of the world have all switched to the new hot app called BAPC (Bidirectional and Private Communication). This app has some stricter social rules than previous iterations. For example, if someone says goodbye using Later!, the other person is expected to reply with Alligator!. You can not keep track of all these social convention sand decide to automate any necessary responses, starting with the most important one: the greetings. When your conversational partner opens with he…ey, you have to respond with hee…eey as well, but using twice as many e’s! Givenastringoftheformhe…eyoflengthatmost1000, print the greeting you will respond with, containing twice as many e’s.

Input
• The input consists of one line containing a single string s as specified, of length at least 3 and at most 1000.

Output
Output the required response.
在这里插入图片描述

#include <iostream>
#include <string>
using namespace std;

int main(){
    string s,ans="";
    cin>>s;
    for(int i=0;i<s.size();i++){
        ans+=s[i];
        if(s[i]=='e') ans+='e';
    }
    cout<<ans<<endl;
    return 0;
}

I - Inquiry I(暴力)

题目链接

The Bureau for Artificial Problem sin Competitions wants you to solve the following problem: Given n positive integers a1,…,an, what is the maximal value of (a12+···+ak2)·(ak+1+···+an)?

Input
• A single line containing an integer 2≤ n ≤106.
• Then follow n lines, the ith of which contains the integer 1≤ ai ≤100. Output

Output
the maximal value of the given expression.
在这里插入图片描述

1.题目大意:给出一个序列,求(a12+···+ak2)·(ak+1+···+an)的最大值,题目没说k的大小,现在看来应该是1<=k<=n,即前后都至少一个数

2.保存ai2和ai的前缀和,进行一次暴力求解,时间复杂度O(n)

#include <iostream>

using namespace std;
const int maxn=1e6+10;
typedef long long ll;
int a[maxn],b[maxn];
ll sum1[maxn],sum2[maxn];

int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        b[i]=a[i]*a[i];
        sum1[i]=sum1[i-1]+a[i];
        sum2[i]=sum2[i-1]+b[i];
    }
    ll ans=-1;
    for(int i=1;i<n;i++){
        ans=max(ans,sum2[i]*(sum1[n]-sum1[i]));
    }
    cout<<ans<<endl;
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值