您的位置:首页 > 其它

BUAA-SCSE 暑期算法提高班 Final Contest

2013-07-13 22:29 211 查看
虽然昂神已经发了解题报告

但白天做的太匆忙,睡前还是稍微总结一下的吧

白天8点到9点扫了一眼晚上的计组实验,比较水

然后逛hust oj 发现今天木有比赛

无意中在bnuoj上发现了今天的final contest

开心啊


A. Ancient Cipher

Time Limit: 3000ms
Case Time Limit: 3000ms
Memory Limit: 131072KB

64-bit integer IO format: %lld Java class name: Main

Submit Status PID:
9389

Font Size:
+

-

[PDF Link]
Ancient Roman empire had a strong government system with various departments, including a secret service department. Important documents were sent between provinces and the capital in encrypted form to prevent eavesdropping. The most popular ciphers in those
times were so called substitution cipher and permutation
cipher. Substitution cipher changes all occurrences of each letter to some other letter. Substitutes for all letters must be different. For some letters substitute letter may coincide with the original letter. For example, applying substitution cipher
that changes all letters from `A' to `Y' to the next ones in the alphabet, and changes `Z'
to `A', to the message ``VICTORIOUS'' one gets the message ``WJDUPSJPVT''.
Permutation cipher applies some permutation to the letters of the message. For example, applying the permutation

2,
1, 5, 4, 3, 7, 6, 10, 9, 8

to the message ``VICTORIOUS''
one gets the message ``IVOTCIRSUO''. It was quickly noticed that being applied separately, both substitution cipher and permutation cipher were rather weak. But when being combined,
they were strong enough for those times. Thus, the most important messages were first encrypted using substitution cipher, and then the result was encrypted using permutation cipher. Encrypting the message ``VICTORIOUS''
with the combination of the ciphers described above one gets the message ``JWPUDJSTVP''. Archeologists have recently found the message engraved on a stone plate. At the first glance
it seemed completely meaningless, so it was suggested that the message was encrypted with some substitution and permutation ciphers. They have conjectured the possible text of the original message that was encrypted, and now they want to check their conjecture.
They need a computer program to do it, so you have to write one.


Input

Input file contains several test cases. Each of them consists of two lines. The first line contains the message engraved on the plate. Before encrypting, all spaces and punctuation marks were removed, so the
encrypted message contains only capital letters of the English alphabet. The second line contains the original message that is conjectured to be encrypted in the message on the first line. It also contains only capital letters of the English alphabet. The
lengths of both lines of the input file are equal and do not exceed 100.


Output

For each test case, print one output line. Output `YES' if the message on the first line of the input file could be the result of encrypting
the message on the second line, or `NO' in the other case.


Sample Input

JWPUDJSTVP
VICTORIOUS
MAMA
ROME
HAHA
HEHE
AAA
AAA
NEERCISTHEBEST
SECRETMESSAGES



Sample Output

YES
NO
YES
YES
NO


/*
其实是水题
不管经历哪种变换
字母出现的次数不变
并且如果两串相应位置的次数相同,一定能够通过变换得到
计数后排序比较就好
*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
int main()
{
char s[105];
char t[105];
int cnt1[30];
int cnt2[30];
while(cin>>s>>t)
{
memset(cnt1,0,sizeof(cnt1));
memset(cnt2,0,sizeof(cnt2));
int flag=1;
for(int i=0;i<strlen(s);i++)
{
cnt1[s[i]-'A']++;
cnt2[t[i]-'A']++;
}
sort(cnt1,cnt1+26);
sort(cnt2,cnt2+26);
for(int i=0;i<26;i++)
{
if(cnt1[i]!=cnt2[i])
{
cout<<"NO"<<endl;
flag=0;
break;
}
}
if(flag)
{
cout<<"YES"<<endl;
}
}
return 0;
}



B. I Can Guess the Data Structure!

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 131072KB

64-bit integer IO format: %lld Java class name: Main

Submit Status PID:
20413

Font Size:
+

-

[PDF Link]


Problem I


I Can Guess the Data Structure!

There is a bag-like data structure, supporting two operations:
1 x


Throw an element x into the bag.
2


Take out an element from the bag.

Given a sequence of operations with return values, you're going to guess the data structure. It is a stack (Last-In, First-Out), a queue (First-In, First-Out), a priority-queue (Always take out larger elements first) or something else that you can hardly imagine!


Input

There are several test cases. Each test case begins with a line containing a single integer n (1<=n<=1000). Each of the next n lines is either a type-1 command, or an integer 2 followed by an integer x. That means after executing a type-2 command, we get an
element x without error. The value of x is always a positive integer not larger than 100. The input is terminated by end-of-file (EOF). The size of input file does not exceed 1MB.


Output

For each test case, output one of the following:
stack


It's definitely a stack.
queue


It's definitely a queue.
priority queue


It's definitely a priority queue.
impossible


It can't be a stack, a queue or a priority queue.
not sure


It can be more than one of the three data structures mentioned above.


Sample Input

6
1 1
1 2
1 3
2 1
2 2
2 3
6
1 1
1 2
1 3
2 3
2 2
2 1
2
1 1
2 2
4
1 2
1 1
2 1
2 2
7
1 2
1 5
1 1
1 3
2 5
1 4
2 4


Output for the Sample Input

queue
not sure
impossible
stack
priority queue


Rujia Liu's Present 3: A Data Structure Contest Celebrating the 100th Anniversary of Tsinghua University

Special Thanks: Yiming Li

Note: Please make sure to test your program with the gift I/O files before submitting!
/*
StL模拟三种操作就好
*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<stack>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
stack<int>s;
queue<int>q;
priority_queue<int>que;
int isstack=1;
int isqueue=1;
int ispq=1;
for(int i=0;i<n;i++)
{
int x,y;
cin>>x>>y;
if(x==1)
{
if(isstack)
{
s.push(y);
}
if(isqueue)
{
q.push(y);
}
if(ispq)
{
que.push(y);
}
}
else
{
if(isstack)
{
if(s.empty())
{
isstack=0;
}
else
{
int temp=s.top();
s.pop();
if(temp!=y)
{
isstack=0;
}
}
}
if(isqueue)
{
if(q.empty())
{
isqueue=0;
}
else
{
int temp=q.front();
q.pop();
if(temp!=y)
{
isqueue=0;
}
}
}
if(ispq)
{
if(que.empty())
{
ispq=0;
}
else
{
int temp=que.top();
que.pop();
if(temp!=y)
{
ispq=0;
}
}
}
}
}
if(isstack+isqueue+ispq>1)
{
cout<<"not sure"<<endl;
}
else if(isstack+isqueue+ispq==0)
{
cout<<"impossible"<<endl;
}
else if(isstack)
{
cout<<"stack"<<endl;
}
else if(isqueue)
{
cout<<"queue"<<endl;
}
else
{
cout<<"priority queue"<<endl;
}
}
return 0;
}



C. Apocalypse Someday

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 131072KB

64-bit integer IO format: %lld Java class name: Main

Submit Status PID:
3327

Font Size:
+

-

The number 666 is considered to be the occult “number of the beast” and is a well used number in all major apocalypse themed blockbuster movies. However the number 666 can’t always be used in the script so numbers such as 1666 are used instead. Let us call
the numbers containing at least three contiguous sixes beastly numbers. The first few beastly numbers are 666, 1666, 2666, 3666, 4666, 5666…

Given a 1-based index n, your program should return the nth beastly number.


Input

The first line contains the number of test cases T (T ≤ 1,000).

Each of the following T lines contains an integer n (1 ≤ n ≤
50,000,000) as a test case.


Output

For each test case, your program should output the nth beastly number.


Sample Input

3
2
3
187



Sample Output

1666
2666
66666


数位dp一点都不会,明天去好好学习一下,正好bnuoj上前几天也看到了数位dp的专题

/*
比赛的时候不会数位dp
昨天学习了一天
今天很轻松啊~
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define INF 0x3f3f3f3f
using namespace std;
long long dp[20][4];
int bit[20];
//have 0: 未出现666 1:未出现666但最高位为6 2:未出现666但最高位为66 3:出现666
long long dfs(int pos,int have,int doing)
{
if(pos==-1)
{
if(have==3)
{
return 1;
}
else
{
return 0;
}
}
if(!doing&&dp[pos][have]!=-1)
{
return dp[pos][have];
}
long long ans=0;
int end=doing?bit[pos]:9;
for(int i=0;i<=end;i++)
{
int nhave=have;
if(have==0)
{
if(i==6)
{
nhave=1;
}
else
{
nhave=0;
}
}
else if(have==1)
{
if(i==6)
{
nhave=2;
}
else
{
nhave=0;
}
}
else if(have==2)
{
if(i==6)
{
nhave=3;
}
else
{
nhave=0;
}
}
ans+=dfs(pos-1,nhave,doing&&i==end);
}
if(!doing)
{
dp[pos][have]=ans;
}
return ans;
}
long long solve(long long n)
{
int len=0;
while(n)
{
bit[len++]=n%10;
n/=10;
}
return dfs(len-1,0,1);
}

int main()
{
memset(dp,-1,sizeof(dp));
int T;
cin>>T;
while(T--)
{
int k;
cin>>k;
long long left=666;
long long right=10000000000LL;
long long mid;
while(left<right)
{
mid=(left+right)/2;
if(solve(mid)>=k)
{
right=mid;
}
else
{
left=mid+1;
}
}
cout<<left<<endl;
}
return 0;
}



D. Fire!

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 131072KB

64-bit integer IO format: %lld Java class name: Main

Submit Status PID:
20042

Font Size:
+

-

[PDF Link]


Problem B: Fire!


Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of the
maze neglected to create a fire escape plan. Help Joe escape the maze.

Given Joe's location in the maze and which squares of the maze are on fire, you must determine whether Joe can exit the maze before the fire reaches him, and how fast he can do it.

Joe and the fire each move one square per minute, vertically or horizontally (not diagonally). The fire spreads all four directions from each square that is on fire. Joe may exit the maze from any square that borders the edge of the maze. Neither Joe nor the
fire may enter a square that is occupied by a wall.


Input Specification

The first line of input contains a single integer, the number of test cases to follow. The first line of each test case contains the two integers R and C,
separated by spaces, with 1 <= R,C <= 1000. The following R lines
of the test case each contain one row of the maze. Each of these lines contains exactly C characters, and each of these characters is one of:

#, a wall

., a passable square

J, Joe's initial position in the maze, which is a passable square

F, a square that is on fire

There will be exactly one J in each test case.


Sample Input

2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F


Output Specification

For each test case, output a single line containing IMPOSSIBLE if Joe cannot exit the maze before the fire reaches him, or an integer giving the earliest time Joe can safely exit the
maze, in minutes.


Output for Sample Input

3
IMPOSSIBLE


bfs自己在刚开始入门的时候重点写过。。。比较顺手。。

而且我这个人不太怕麻烦。。。。。。勤能补拙。。。

/*
第一次bfs确定每个点着火的时间
第二次bfs判断人能否逃出
*/
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define INF 0x3f3f3f3f
using namespace std;
struct node
{
int x;
int y;
int step;
};
queue<node>q;
node s;
node next;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
char map[1005][1005];
int visit[1005][1005];
int timeneed[1005][1005];
int firex[1005];
int firey[1005];
int k;
int sx,sy;
int n,m;
int check(int x,int y)
{
if(x>=0&&x<n&&y>=0&&y<m&&!visit[x][y]&&map[x][y]=='.')
{
return 1;
}
else
{
return 0;
}
}
int edge(int x,int y)
{
if(x==0||x==n-1||y==0||y==m-1)
{
return 1;
}
else
{
return 0;
}
}
void bfsfire()
{
memset(visit,0,sizeof(visit));
while(!q.empty())
{
q.pop();
}
//	cout<<k<<endl;
for(int i=0;i<k;i++)
{
node temp;
temp.x=firex[i];
temp.y=firey[i];
temp.step=0;
q.push(temp);
timeneed[temp.x][temp.y]=0;
visit[temp.x][temp.y]=1;
}
while(!q.empty())
{
node s=q.front();
q.pop();
for(int i=0;i<4;i++)
{
next.x=s.x+dx[i];
next.y=s.y+dy[i];
next.step=s.step+1;
//			cout<<next.x<<" "<<next.y<<endl;
if(check(next.x,next.y))
{
q.push(next);
visit[next.x][next.y]=1;
timeneed[next.x][next.y]=next.step;
//			cout<<time[next.x][next.y]<<endl;
}
}
}
}
int bfs()
{
memset(visit,0,sizeof(visit));
while(!q.empty())
{
q.pop();
}
s.x=sx;
s.y=sy;
s.step=0;
q.push(s);
visit[s.x][s.y]=1;
while(!q.empty())
{
s=q.front();
q.pop();
for(int i=0;i<4;i++)
{
next.x=s.x+dx[i];
next.y=s.y+dy[i];
next.step=s.step+1;
if(check(next.x,next.y)&&next.step<timeneed[next.x][next.y])
{
if(edge(next.x,next.y))
{
return next.step;
}
q.push(next);
visit[next.x][next.y]=1;
}
}
}
return 0;
}
int main()
{
int T;
cin>>T;
while(T--)
{
memset(timeneed,INF,sizeof(timeneed));
cin>>n>>m;
k=0;
for(int i=0;i<n;i++)
{
cin>>map[i];
for(int j=0;j<m;j++)
{
if(map[i][j]=='J')
{
sx=i;
sy=j;
}
else if(map[i][j]=='F')
{
firex[k]=i;
firey[k++]=j;
}
}
}
if(edge(sx,sy))
{
cout<<"1"<<endl;
continue;
}
bfsfire();
/*
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cout<<time[i][j]<<" ";
}
cout<<endl;
}
*/
int ans=bfs();
if(ans)
{
cout<<ans+1<<endl;
}
else
{
cout<<"IMPOSSIBLE"<<endl;
}
}
return 0;
}



E. Out of Hay

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 65536KB

64-bit integer IO format: %lld Java class name: Main

Submit Status PID:
2514

Font Size:
+

-

The cows have run out of hay, a horrible event that must be remedied immediately. Bessie intends to visit the other farms to survey their hay situation. There are N (2 <= N <= 2,000) farms (numbered 1..N);
Bessie starts at Farm 1. She'll traverse some or all of the M (1 <= M <= 10,000) two-way roads whose length does not exceed 1,000,000,000 that connect the farms. Some farms may be multiply connected with different length roads. All farms are connected one
way or another to Farm 1.

Bessie is trying to decide how large a waterskin she will need. She knows that she needs one ounce of water for each unit of length of a road. Since she can get more water at each farm, she's only concerned about the length of the longest road. Of course, she
plans her route between farms such that she minimizes the amount of water she must carry.

Help Bessie know the largest amount of water she will ever have to carry: what is the length of longest road she'll have to travel between any two farms, presuming she chooses routes that minimize that number? This means, of course, that she might backtrack
over a road in order to minimize the length of the longest road she'll have to traverse.


Input

* Line 1: Two space-separated integers, N and M.

* Lines 2..1+M: Line i+1 contains three space-separated integers, A_i, B_i, and L_i, describing a road from A_i to B_i of length L_i.


Output

* Line 1: A single integer that is the length of the longest road required to be traversed.


Sample Input

3 3
1 2 23
2 3 1000
1 3 43



Sample Output

43



Hint

OUTPUT DETAILS:

In order to reach farm 2, Bessie travels along a road of length 23. To reach farm 3, Bessie travels along a road of length 43. With capacity 43, she can travel along these roads provided that she refills her tank to maximum capacity before she starts down a
road.
这题MST裸题。。前天刚写过这题。。。

/*
prim算法
和dijkstra太像了
*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define INF 0x3f3f3f3f
using namespace std;
int n,m;
int map[2005][2005];
int dis[2005];
int visit[2005];
void prim()
{
memset(visit,0,sizeof(visit));
for(int i=1;i<=n;i++)
{
dis[i]=map[1][i];
}
visit[1]=1;
int ans=0;
for(int i=1;i<=n;i++)
{
int mark=1;
int mindist=INF;
for(int j=1;j<=n;j++)
{
if(!visit[j]&&dis[j]<mindist)
{
mindist=dis[j];
mark=j;
}
}
visit[mark]=1;
if(mindist==INF)//最小生成树注意跳出
{
break;
}
ans=max(ans,mindist);
for(int j=1;j<=n;j++)
{
if(!visit[j])
{
dis[j]=min(dis[j],map[mark][j]);//只有这里不一样
}
}
}
cout<<ans<<endl;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
map[i][j]=i==j?0:INF;
}
}
for(int i=1;i<=m;i++)
{
int x,y,l;
cin>>x>>y>>l;
map[x][y]=map[y][x]=min(map[x][y],l);
}
prim();
return 0;
}



F. Cable master

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 10000KB

64-bit integer IO format: %lld Java class name: Main

Submit Status PID:
1183

Font Size:
+

-

Inhabitants of the Wonderland have decided to hold a regional programming contest. The Judging Committee has volunteered and has promised to organize the most honest contest ever. It was decided to connect
computers for the contestants using a "star" topology - i.e. connect them all to a single central hub. To organize a truly honest contest, the Head of the Judging Committee has decreed to place all contestants evenly around the hub on an equal distance from
it.

To buy network cables, the Judging Committee has contacted a local network solutions provider with a request to sell for them a specified number of cables with equal lengths. The Judging Committee wants the cables to be as long as possible to sit contestants
as far from each other as possible.

The Cable Master of the company was assigned to the task. He knows the length of each cable in the stock up to a centimeter,and he can cut them with a centimeter precision being told the length of the pieces he must cut. However, this time, the length is not
known and the Cable Master is completely puzzled.

You are to help the Cable Master, by writing a program that will determine the maximal possible length of a cable piece that can be cut from the cables in the stock, to get the specified number of pieces.


Input

The first line of the input file contains two integer numb ers N and K, separated by a space. N (1 = N = 10000) is the number of cables in the stock, and K (1 = K = 10000) is the number of requested pieces.
The first line is followed by N lines with one number per line, that specify the length of each cable in the stock in meters. All cables are at least 1 meter and at most 100 kilometers in length. All lengths in the input file are written with a centimeter
precision, with exactly two digits after a decimal point.


Output

Write to the output file the maximal length (in meters) of the pieces that Cable Master may cut from the cables in the stock to get the requested number of pieces. The number must be written with a centimeter
precision, with exactly two digits after a decimal point.

If it is not possible to cut the requested number of pieces each one being at least one centimeter long, then the output file must contain the single number "0.00" (without quotes).


Sample Input

4 11
8.02
7.43
4.57
5.39



Sample Output

2.00


二分裸题,不过这题貌似g++和c++不同?好像是g++对浮点数的执行不同?不太明白

/*
G++和C++结果不同?
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define MIN 1E-6
using namespace std;
double a[10005];
int n,k;
int ok(double x)
{
int sum=0;
for(int i=0;i<n;i++)
{
sum+=(int)(a[i]/x);
}
if(sum>=k)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
while(cin>>n>>k)
{
double right=0;
for(int i=0;i<n;i++)
{
cin>>a[i];
right=max(right,a[i]);
}
double left=0;
double mid;
int flag;
while(right-left>MIN)
{
mid=(left+right)/2;
if(ok(mid))
{
left=mid;
flag=1;
}
else
{
right=mid;
}
}
if(!flag)
{
cout<<"0.00"<<endl;
}
else
{
printf("%.2lf\n",(int)(right*100)*0.01);
}
}
return 0;
}



G. SPIN

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 65536KB

64-bit integer IO format: %lld Java class name: Main

Submit Status PID:
2435

Font Size:
+

-

Simulate a locked spinner puzzle.

A locked spinner puzzle is a puzzle where you can only change wheels in groups. It is a common puzzle to achieve some value on the spinners by only changing them in the allowed groups.

Imagine a row of D numbered wheels, each labeled sequentially with the digits 0 through 9. This is similar to what is on a briefcase combination lock.

Below this are a series of B buttons with labels that are D digits long. For example, D may be 4 and the labels are 1000 1200 1002 0111 and 0100. Pressing the button labeled 1000 moves the first wheel once, but leaves the others alone, while pressing the button
labeled 1002 moves the first wheel once and the fourth wheel twice, leaving the center wheels unchanged.

Your task is to simulate such a locked spinner puzzle giving the final readout of the wheels.


Input

The input to your program will be a line containing D digits (at most 10) representing the starting positions of the wheels. Following this, each line will have the button label for which button is pressed
next.There will always be at least 1 digit


Output

Output the final positions of the wheels.


Sample Input

0001
1003
0206
0034
1111
1003



Sample Output

3348


/*
大水题
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
int main()
{
int ans[15];
char s[15];
int len;
memset(ans,0,sizeof(ans));
while(cin>>s)
{
len=strlen(s);
for(int i=0;i<len;i++)
{
ans[i]+=s[i]-'0';
ans[i]=ans[i]%10;
//			cout<<ans[i]<<endl;
}
}
//	cout<<len<<endl;
for(int i=0;i<len;i++)
{
cout<<ans[i];
}
cout<<endl;
return 0;
}



H. Two Strings

Time Limit: 3000ms
Case Time Limit: 3000ms
Memory Limit: 65536KB

64-bit integer IO format: %lld Java class name: Main

Submit Status PID:
29375

Font Size:
+

-

Eyelids loves playing strings very much. One day he has two strings S and
W, both consisting of lowercase letters and having length of m. For each string he has two operations to change the letters:
1. Swap two adjacent letters and pay no cost;
2. Change one letter x to y and pay |x-y|.
He wonders the minimal cost to change the string S to W only with the two
operations.


Input

The first line contains a single integer T, indicating the number of test cases.

The first line of each test case contains an integer m (1<=m<=100000), followed by two strings S and W separated by a single space, which only contains lowercase letters.


Output

For each test case, output the case number first, then the minimal cost.


Sample Input

2

3

abc abc

5

bcabc bdcbd


Sample Output

Case 1: 0

Case 2: 4

/*
水题。。
一开始没看到swap操作不需要cost...
*/
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
int main()
{
int T;
cin>>T;
for(int tt=1;tt<=T;tt++)
{
char s[100005];
char t[100005];
int m;
cin>>m;
cin>>s;
cin>>t;
sort(s,s+m);
sort(t,t+m);
int ans=0;
for(int i=0;i<m;i++)
{
ans+=abs(s[i]-t[i]);
}
cout<<"Case "<<tt<<": "<<ans<<endl;
}
return 0;
}



I. Space Elevator

Time Limit: 1000ms
Case Time Limit: 1000ms
Memory Limit: 65536KB

64-bit integer IO format: %lld Java class name: Main

Submit Status PID:
2511

Font Size:
+

-

The cows are going to space! They plan to achieve orbit by building a sort of space elevator: a giant tower of blocks. They have K (1 <= K <= 400) different types of blocks with which to build the tower. Each
block of type i has height h_i (1 <= h_i <= 100) and is available in quantity c_i (1 <= c_i <= 10). Due to possible damage caused by cosmic rays, no part of a block of type i can exceed a maximum altitude a_i (1 <= a_i <= 40000).

Help the cows build the tallest space elevator possible by stacking blocks on top of each other according to the rules.


Input

* Line 1: A single integer, K

* Lines 2..K+1: Each line contains three space-separated integers: h_i, a_i, and c_i. Line i+1 describes block type i.


Output

* Line 1: A single integer H, the maximum height of a tower that can be built


Sample Input

3
7 40 3
5 23 8
2 52 6



Sample Output

48



Hint

OUTPUT DETAILS:

From the bottom: 3 blocks of type 2, below 3 of type 1, below 6 of type 3. Stacking 4 blocks of type 2 and 3 of type 1 is not legal, since the top of the last type 1 block would exceed height 40.
/*
多重背包
稀里糊涂套模版。。
*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
int f[40005];
int m;
struct node
{
int h;
int a;
int c;
}cow[405];
int cmp(const node &x,const node &y)
{
return x.a<y.a;
}
void ZeroOnePack(int cost,int weight)//cost 为费用, weight 为价值
{
for(int i=weight;i>=cost;i--)
if(f[i-cost])
f[i]=1;
}
void CompletePack(int cost,int weight)
{
for(int i=cost;i<=weight;i++)
if(f[i-cost])
f[i]=1;
}
void MultiplePack(int cost,int weight,int amount)
{
if(cost*amount>=weight)
CompletePack(cost,weight);
else
{
for(int k=1;k<amount;)
{
ZeroOnePack(k*cost,weight);
amount-=k;
k<<=1;
}
ZeroOnePack(amount*cost,weight);
}
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>cow[i].h>>cow[i].a>>cow[i].c;
}
sort(cow+1,cow+n+1,cmp);
memset(f,0,sizeof(f));
f[0]=1;
for(int i=1;i<=n;i++)
{
MultiplePack(cow[i].h,cow[i].a,cow[i].c);
}
for(int i=cow
.a;i>=0;i--)
{
if(f[i])
{
cout<<i<<endl;
break;
}
}
return 0;
}


水题和裸题比较多TT

小学期结束后想回趟家。。也算休息休息回来开始22号的集训吧。。

反正是抱着学习的心态去的也就不必在意队友了。。。

加油~

ps:这一届大一的同学貌似热情要比我们那一届高好多。。。

自己起步太晚了。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: