您的位置:首页 > 编程语言 > C语言/C++

Round A APAC Test 2017

2016-07-10 23:33 405 查看
题目链接:https://code.google.com/codejam/contest/11274486/dashboard

结果真是遗憾,排名比200多一点点。败在了对规则的不了解上,当然实力还是渣。唉毕竟第一次比赛,才发现居然tmd和练习赛是不一样的。分数最高的第四题大数据,我下载下来开始运行然后喝了个水去了个厕所,回来就显示超时了,最重要的是发现不能再次下载(小数据就算incorrect还是可以重新下载数据然后运行提交的)。一开始我以为是它平台的bug,于是无限次刷新,换浏览器,重启电脑,发现还是这样。时间就这样耗过去了,比赛结束才知道大数据就一次提交机会,切记切记!最伤心的是我的程序是对的。唉,就当交学费了吧。

记录一下吧:

Problem A. Country Leader

The Constitution of a certain country states that the leader is the person with the name containing the greatest number of different alphabet letters. (The country uses the uppercase English alphabet from A through Z.) For example, the name GOOGLE has four
different alphabet letters: E, G, L, and O. The name APAC CODE JAM has eight different letters. If the country only consists of these 2 persons, APAC CODE JAM would be the leader.

If there is a tie, the person whose name comes earliest in alphabetical order is the leader.

Given a list of names of the citizens of the country, can you determine who the leader is?

Input

The first line of the input gives the number of test cases, T. T test cases follow. Each test case starts with a line with an interger N, the number of people in the country. Then N lines follow. The i-th line represents the name of the i-th person. Each name
contains at most 20 characters and contains at least one alphabet letter.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the name of the leader.

Limits

1 ≤ T ≤ 100.

1 ≤ N ≤ 100.

Small dataset:Each name consists of at most 20 characters and only consists of the uppercase English letters A through Z.

Large dataset:Each name consists of at most 20 characters and only consists of the uppercase English letters A through Z and ' '(space).

All names start and end with alphabet letters.

题意:给定若干个只含有大写字母和空格的字符串,按照特定的规则选出最牛逼的。规则是先比较出现的字母数量,如果相同,则按照字典序排序。

思路:直接模拟呗,大小数据N都是小于100,所以直接排序也没什么问题。

#include <cstdio>
#include <cstring>
#include <vector>
#include <string>
using namespace std;
int T,n,m;
struct node{
char s[25];
int t;
}s[105];
int flag[258];
int cmp(node a,node b){
if(a.t == b.t)
return strcmp(a.s, b.s)<0;
return a.t>b.t;
}
int main(){
scanf("%d",&T);
for(int z = 1;z<=T;z++){
scanf("%d\n",&n);
for(int i = 0;i<n;i++){
gets(s[i].s);
memset(flag, 0, sizeof(flag));
for(int j = 0;s[i].s[j];j++)
if(s[i].s[j] !=' ')
flag[s[i].s[j]-'A'] = 1;
s[i].t = 0;
for(int j = 0;j<26;j++)
if(flag[j])
s[i].t++;
}
sort(s,s+n,cmp);
printf("Case #%d: %s\n",z,s[0].s);
}
return 0;
}

Problem B. Rain
There's an island in the sea. The island can be described as a matrix with R rows and C columns, with H[i][j] indicating the height of each unit cell. Following is an example of a 3*3 island:

3 5 5

5 4 5

5 5 5

Sometimes, a heavy rain falls evenly on every cell of this island. You can assume that an arbitrarily large amount of water falls. After such a heavy rain, some areas of the island (formed of one or more unit cells joined along edges) might collect water. This
can only happen if, wherever a cell in that area shares an edge (not just a corner) with a cell outside of that area, the cell outside of that area has a larger height. (The surrounding sea counts as an infinite grid of cells with height 0.) Otherwise, water
will always flow away into one or more of the neighboring areas (for our purposes, it doesn't matter which) and eventually out to sea. You may assume that the height of the sea never changes. We will use W[i][j] to denote the heights of the island's cells
after a heavy rain. Here are the heights of the example island after a heavy rain. The cell with initial height 4 only borders cells with higher initial heights, so water will collect in it, raising its height to 5. After that, there are no more areas surrounded
by higher cells, so no more water will collect. Again, note that water cannot flow directly between cells that intersect only at their corners; water must flow along shared edges.

Following is the height of the example island after rain:

3 5 5

5 5 5

5 5 5

Given the matrix of the island, can you calculate the total increased height sum(W[i][j]-H[i][j]) after a heavy rain?

Input

The first line of the input gives the number of test cases, T. T test cases follow.

The first line of each test case contains two numbers R and C indicating the number of rows and columns of cells on the island. Then, there are R lines of C positive integers each. The j-th value on the i-th of these lines gives H[i][j]: the height of the cell
in the i-th row and the j-th column.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the total increased height.

Limits

1 ≤ T ≤ 100.

1 ≤ H[i][j] ≤ 1000.

Small dataset

1 ≤ R ≤ 10.

1 ≤ C ≤ 10.

Large dataset

1 ≤ R ≤ 50.

1 ≤ C ≤ 50.

题意:一个n*m矩形区域,其中每个1*1都是有高度的矩形块,高低起伏,求最多储水量。(边界不能储水)

思路:先将边界装入优先队列中(高度越小越优先),并标记为已访问。看队首元素四周未访问过的点,1、如果该点不比队首低,则将它加入队列,标记为已访问,即它变成了新的边界。2、该点比队首低,意味着该点可以储水,更新res值,同时将它加入队列中,但是它的高度为原队首元素的高度,即以它为边界的点不能超过这个高度,同时将该点标记为已访问。

#include <cstdio>
#include <cstring>
#include <queue>
#include <string>
using namespace std;
#define N 55
int s

,used

,res;
int T,n,m;
struct node{
int x,y,h;
node(int xx,int yy,int hh):x(xx),y(yy),h(hh){};
bool operator<(const node b)const{
return h>b.h;
}
};
int ori[4][2] = {{0,-1},{0,1},{-1,0},{1,0}};
int check(int x,int y){
return x>=0&&x<n&&y>=0&&y<m&&(!used[x][y]);
}
int main(){
scanf("%d",&T);
for(int z = 1;z<=T;z++){
res = 0;
memset(used, 0, sizeof(used));
priority_queue<node> q;
scanf("%d %d",&n,&m);
for(int i = 0;i<n;i++)
for(int j = 0;j<m;j++){
scanf("%d",&s[i][j]);
if(i==0||i==n-1||j==0||j==m-1){
q.push(node(i,j,s[i][j]));
used[i][j] = 1;
}
}
while(!q.empty()){
node now = q.top();
q.pop();
for(int i = 0;i<4;i++){
int xx = now.x+ori[i][0];
int yy = now.y+ori[i][1];
if(check(xx, yy)){
if(s[xx][yy] >= now.h)
q.push(node(xx,yy,s[xx][yy]));
else{
res += now.h-s[xx][yy];
q.push(node(xx,yy,now.h));
}
used[xx][yy] = 1;
}
}
}
printf("Case #%d: %d\n",z,res);
}
return 0;
}

Problem C. Jane's Flower Shop
Jane plans to open a flower shop in the local flower market. The initial cost includes the booth license, furnishings and decorations, a truck to transport flowers from the greenhouse to the shop, and so on. Jane will have to recoup these costs by earning
income. She has estimated how much net income she will earn in each of the following M months.

Jane wants to predict how successful her flower shop will be by calculating the IRR (Internal Rate of Return) for the M-month period. Given a series of (time, cash flow) pairs (i, Ci), the IRR is the compound interest rate that would make total cash exactly
0 at the end of the last month. The higher the IRR is, the more successful the business is. If the IRR is lower than the inflation rate, it would be wise not to start the business in the first place.

For example, suppose the initial cost is $10,000 and the shop runs for 3 months, with net incomes of $3,000, $4,000, and $5,000, respectively. Then the IRR r is given by:

-10000*(r+1)^3 + 3000*(r+1)^2 + 4000*(r+1) + 5000 = 0

In this case, there is only one rate (~=8.8963%) that satisfies the equation.

Help Jane to calculate the IRR for her business. It is guaranteed that -1 < r < 1, and there is exactly one solution in each test case.

Input

The first line of the input gives the number of test cases, T. T test cases follow. Each test case starts with a positive integer M: the number of months that the flower shop will be open. The next line contains M + 1 non-negative integers Ci (0 ≤ i ≤ M). Note
that C0 represents the initial cost, all the remaining Cis are profits, the shop will always either make a positive net profit or zero net profit in each month, and will never have negative profits.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is a floating-point number: the IRR of Jane's business. y will be considered correct if it is within an absolute or relative error of 10-9 of
the correct answer. See the FAQ for an explanation of what that means, and what formats of real numbers we accept.

Limits

1 ≤ T ≤ 100.

C0 > 0.

0 ≤ Ci ≤ 1,000,000,000.

Small dataset

1 ≤ M ≤ 2.

Large dataset

1 ≤ M ≤ 100.

题意:题意很简单,就是给一个方程,题目保证解唯一,求这个解。

思路:这道题真是觉得自己没用,其实很简单。一开始没细想直接写了个二分,写到一半发现没考虑单调性,然后求了个导发现没用。然后就手足无措中,以为要用模拟退火等等高科技了。怕耽误太久就先把小数据过了(这个小数据的范围明摆了就是解方程,一次方程和二次方程,好在公式还没忘)。比赛结束自己又想了一下,顿时捶胸顿足,显然r=-1的时候方程值大于0,而解又保证唯一,那么在r∈[-1,1]之间,必然零点左边都是大于0,右边都是小于0的。所以就是二分,擦。。。

#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
using namespace std;
#define N 105
int s
;
int T,n,m;
int test(double &x){
double sum = -s[0]*pow((1+x),n);
for(int i = 1;i<=n;i++)
sum += s[i] * pow((1+x),n-i);
if(sum > 1e-15)
return 1;
if(sum < -1e-15)
return -1;
return 0;
}
int main(){
scanf("%d",&T);
for(int z = 1;z<=T;z++){
scanf("%d",&n);
for(int i = 0;i<=n;i++)
scanf("%d",&s[i]);
double low = -1.,high = 1.,mid;
while(high-low >= 1e-15){
mid = (low+high) / 2;
int j = test(mid);
if(j<0)
high = mid;
else if(j>0)
low = mid;
else
break;
}
printf("Case #%d: %.12lf\n",z,mid);
}
return 0;
}



Problem D. Clash Royale

Clash Royale is a real time strategy card game. Each card has an attack power and a level. Each player picks 8 cards to form a battle deck; the total attack power of a deck is the sum of the attack power of each of its cards. Players fight with each other
by placing cards from their battle decks into the battle arena. The winner of a battle is rewarded with coins, which can be used to upgrade cards. Upgrading a card increases its attack power. <p/>

After days of arena fighting, Little Shawn has accumulated a total of M coins. He has decided to upgrade some of his cards. Little Shawn has N cards. The i-th card can have any level from 1 through Ki; the attack power for the j-th level is Ai,j. Cards must
be upgraded one level at a time; the price to upgrade the i-th card from level j to level j+1 costs Ci,j coins. The i-th card is currently at level Li before Little Shawn has upgraded any cards.

Little Shawn wants to use some or all of his coins to upgrade cards, and then form a deck of exactly 8 cards, so that the deck's total attack power is as large as possible. Can you help him do this? He can upgrade the same card more than once as long as he
can afford it, and he does not have to upgrade every card.

Input

The first line of the input gives the number of test cases, T. T test cases follow. Each test case starts with 2 integers M and N, the number of coins and the number of cards that Little Shawn possesses. Then N blocks follow. The i-th block consists of 3 lines
describing the i-th card. The first line contains two integers Ki and Li, the maximum possible level and current level of the card. The second line contains Ki integers Ai,1, Ai,2, ..., Ai,Ki, the attack power of each level. The third line contains Ki-1 integers
Ci,1, Ci,2, ..., Ci,Ki-1, the number of coins required to upgrade a card that is currently at level 1, 2, ..., Ki-1.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the maximal possible total attack power of a deck that Little Shawn can form, using the coins that he has.

Limits

1 ≤ T ≤ 100.

1 ≤ Ki ≤ 10.

1 ≤ Li ≤ Ki.

Ai,j < Ai,j+1.

Small dataset

1 ≤ M ≤ 1,000.

N = 8.

1 ≤ Ai,j ≤ 1,000.

1 ≤ Ci,j ≤ 1,000.

Large dataset

1 ≤ M ≤ 1,000,000,000.

8 ≤ N ≤ 12.

1 ≤ Ai,j ≤ 1,000,000,000.

1 ≤ Ci,j ≤ 1,000,000,000.

题意:一个人有8~12张卡片,每张卡片有其特有的最大的级别,高的级别带来更高的收益,然后升级是需要钱的,升级只能一级一级升,而且从i级升到i+1级别需要的钱都是不同的。现在给定一定的钱数,问最后选出8个卡片,能够达到的最大的收益之和。

思路:反正我的做法在大数据上5s之内跑完,还没仔细想有没有别的做法。思路就是先从12个卡片枚举选出8个来,对于选出来的8个,直接暴搜。复杂度是C12,8 * 10^8。当然里面有两个剪枝:一个是钱数不够了直接退出,另外一个是先预先算出所有卡片升级到最高需要的钱数,暴搜的过程中看看如果后面的都升到最高级也没有最优值好就退出。

#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
using namespace std;
#define N 15
int id
;
int T,n,m;
int k
,level
,a

;
long long c

;
long long p
;
long long res = 0;
int onenum(int x){
int res = 0;
while (x) {
res ++;
x &= (x-1);
}
return res;
}
void dfs(int x,long long sum,int left){
res = max(res,sum);
if(x == 8)
return ;
if(x && sum + p[7]-p[x-1] <= res)
return;
dfs(x+1,sum,left);
for(int i = level[id[x]]+1;i<=k[id[x]];i++){
if(left < c[id[x]][i])
break;
dfs(x+1, sum+a[id[x]][i]-a[id[x]][level[id[x]]], left-c[id[x]][i]);
}
}
int main(){
scanf("%d",&T);
for(int z = 1;z<=T;z++){
res = 0;
scanf("%d %d",&m,&n);
for(int i = 0;i<n;i++){
scanf("%d %d",&k[i],&level[i]);
for(int j = 1;j<=k[i];j++)
scanf("%d",&a[i][j]);
for(int j = 2;j<=k[i];j++)
scanf("%lld",&c[i][j]);
for(int j = level[i]+2;j<=k[i];j++)//变成记录从level[i]升级到j级的花费
c[i][j] += c[i][j-1];
}
for(int i = (1<<8)-1;i<(1<<n);i++){//12个选出8个
if(onenum(i) == 8){
int tmp = 0;
long long sum = 0;
for(int j = 0;j<n;j++)
if((1<<j) & i)
id[tmp++] = j;
for(int j = 0;j<8;j++)
sum += a[id[j]][level[id[j]]];

p[0] = a[id[0]][k[id[0]]]-a[id[0]][level[id[0]]];
for(int i = 1;i<8;i++)
p[i] = p[i-1] + a[id[i]][k[id[i]]]-a[id[i]][level[id[i]]];
dfs(0,sum,m);
}
}
printf("Case #%d: %lld\n",z,res);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  谷歌 c++ 面试 算法 题解