训练-sixsix
A - 最大报销额
现有一笔经费可以报销一定额度的发票。允许报销的发票类型包括买图书(A类)、文具(B类)、差旅(C类),要求每张发票的总额不得超过1000元,每张发票上,单项物品的价值不得超过600元。现请你编写程序,在给出的一堆发票中找出可以报销的、不超过给定额度的最大报销额。
Input测试输入包含若干测试用例。每个测试用例的第1行包含两个正数 Q 和 N,其中 Q 是给定的报销额度,N(<=30)是发票张数。随后是 N 行输入,每行的格式为:
m Type_1:price_1 Type_2:price_2 ... Type_m:price_m
其中正整数 m 是这张发票上所开物品的件数,Type_i 和 price_i 是第 i 项物品的种类和价值。物品种类用一个大写英文字母表示。当N为0时,全部输入结束,相应的结果不要输出。
Output对每个测试用例输出1行,即可以报销的最大数额,精确到小数点后2位。
Sample Input
200.00 3 2 A:23.50 B:100.00 1 C:650.00 3 A:59.99 A:120.00 X:10.00 1200.00 2 2 B:600.00 A:400.00 1 C:200.50 1200.50 3 2 B:600.00 A:400.00 1 C:200.50 1 A:100.00 100.00 0
Sample Output
123.50 1000.00 1200.50
#include"stdio.h" #include"cstdio" #include"algorithm" #include"string.h" #include"map" using namespace std; const int max_n=3*(1e6)+10; double A[35]; int dp[max_n]; int main() { double q; int j,i,n,m; while(scanf("%lf%d",&q,&n)!=EOF) { if(n==0) break; double num; memset(A,0,sizeof(A)); memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { int r=1; char x,y,z; scanf("%d",&m); map <char,double> count; for(j=1;j<=m;j++) { scanf("%c%c%c%lf",&x,&y,&z,&num); count[y]+=num; if(y!='C'&&y!='B'&&y!='A'||num>600) r=0; A[i]+=num;//printf("%f\n",num); } if(count['A']>600||count['B']>600||count['C']>600) r=0; count['A']=0;count['B']=0;count['C']=0; if(A[i]>1000) r=0; if(r==0) A[i]=0; dp[int(A[i]*100)]=1; dp[0]=1; // printf("%lf\n",A[i]); } for(i=1;i<=n;i++) { for(j=int(q*100);j>=int(100*A[i]);j--) { dp[j]+=dp[j-int(100*A[i])]; } } for(i=int(q*100);i>=0;i--) { if(dp[i]) { printf("%.2lf\n",(double(i))/100); break; } } } }
B - Working out
Summer is coming! It's time for Iahub and Iahubina to work out, as they both want to look hot at the beach. The gym where they go is a matrix a with n lines and m columns. Let number a[i][j] represents the calories burned by performing workout at the cell of gym in the i-th line and the j-th column.
Iahub starts with workout located at line 1 and column 1. He needs to finish with workout a[n][m]. After finishing workout a[i][j], he can go to workout a[i + 1][j] or a[i][j + 1]. Similarly, Iahubina starts with workout a[n][1] and she needs to finish with workout a[1][m]. After finishing workout from cell a[i][j], she goes to either a[i][j + 1] or a[i - 1][j].
There is one additional condition for their training. They have to meet in exactly one cell of gym. At that cell, none of them will work out. They will talk about fast exponentiation (pretty odd small talk) and then both of them will move to the next workout.
If a workout was done by either Iahub or Iahubina, it counts as total gain. Please plan a workout for Iahub and Iahubina such as total gain to be as big as possible. Note, that Iahub and Iahubina can perform workouts with different speed, so the number of cells that they use to reach meet cell may differs.
Input
The first line of the input contains two integers n and m (3 ≤ n, m ≤ 1000). Each of the next n lines contains m integers: j-th number from i-th line denotes element a[i][j] (0 ≤ a[i][j] ≤ 105).
Output
The output contains a single number — the maximum total gain possible.
Example
3 3
100 100 100
100 1 100
100 100 100
800
Note
Iahub will choose exercises a[1][1] → a[1][2] → a[2][2] → a[3][2] → a[3][3]. Iahubina will choose exercises a[3][1] → a[2][1] → a[2][2] → a[2][3] → a[1][3].
#include"stdio.h" #include"cstdio" #include"algorithm" #include"string.h" using namespace std; const int max_n=1e3+10; int exe[max_n][max_n],dp1[max_n][max_n],dp2[max_n][max_n]; int dp3[max_n][max_n],dp4[max_n][max_n]; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { int i,j; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) scanf("%d",&exe[i][j]); } memset(dp1,0,sizeof(dp1)); memset(dp2,0,sizeof(dp2)); memset(dp3,0,sizeof(dp3)); memset(dp4,0,sizeof(dp4)); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) dp1[i][j]=max(dp1[i-1][j],dp1[i][j-1])+exe[i][j]; } for(i=1;i<=n;i++) { for(j=m;j>=1;j--) dp2[i][j]=max(dp2[i-1][j],dp2[i][j+1])+exe[i][j]; } for(i=n;i>=1;i--) { for(j=1;j<=m;j++) dp3[i][j]=max(dp3[i+1][j],dp3[i][j-1])+exe[i][j]; } for(i=n;i>=1;i--) { for(j=m;j>=1;j--) dp4[i][j]=max(dp4[i+1][j],dp4[i][j+1])+exe[i][j]; } int ans=0; for(i=2;i<n;i++) { for(j=2;j<m;j++) { ans=max(ans,dp1[i-1][j]+dp4[i+1][j]+dp2[i][j+1]+dp3[i][j-1]); ans=max(ans,dp1[i][j-1]+dp4[i][j+1]+dp2[i-1][j]+dp3[i+1][j]); } } printf("%d\n",ans); } }
C - Attack on Titans
Over centuries ago, mankind faced a new enemy, the Titans. The difference of power between mankind and their newfound enemy was overwhelming. Soon, mankind was driven to the brink of extinction. Luckily, the surviving humans managed to build three walls: Wall Maria, Wall Rose and Wall Sina. Owing to the protection of the walls, they lived in peace for more than one hundred years.
But not for long, a colossal Titan appeared out of nowhere. Instantly, the walls were shattered, along with the illusory peace of everyday life. Wall Maria was abandoned and human activity was pushed back to Wall Rose. Then mankind began to realize, hiding behind the walls equaled to death and they should manage an attack on the Titans.
So, Captain Levi, the strongest ever human being, was ordered to set up a special operation squad of N people, numbered from 1 to N. Each number should be assigned to a soldier. There are three corps that the soldiers come from: the Garrison, the Recon Corp and the Military Police. While members of the Garrison are stationed at the walls and defend the cities, the Recon Corps put their lives on the line and fight the Titans in their own territory. And Military Police serve the King by controlling the crowds and protecting order. In order to make the team more powerful, Levi will take advantage of the differences between the corps and some conditions must be met.
The Garrisons are good at team work, so Levi wants there to be at least M Garrison members assigned with continuous numbers. On the other hand, members of the Recon Corp are all elite forces of mankind. There should be no more than K Recon Corp members assigned with continuous numbers, which is redundant. Assume there is unlimited amount of members in each corp, Levi wants to know how many ways there are to arrange the special operation squad.
Input
There are multiple test cases. For each case, there is a line containing 3 integers N (0 < N < 1000000), M (0 < M < 10000) and K (0 < K < 10000), separated by spaces.
Output
One line for each case, you should output the number of ways mod 1000000007.
Sample Input
3 2 2
Sample Output
5
Hint
Denote the Garrison, the Recon Corp and the Military Police as G, R and P. Reasonable arrangements are: GGG, GGR, GGP, RGG, PGG.
D - The Suspects
Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized as a global threat in mid-March 2003. To minimize transmission to others, the best strategy is to separate the suspects from others.
In the Not-Spreading-Your-Sickness University (NSYSU), there are many student groups. Students in the same group intercommunicate with each other frequently, and a student may join several groups. To prevent the possible transmissions of SARS, the NSYSU collects the member lists of all student groups, and makes the following rule in their standard operation procedure (SOP).
Once a member in a group is a suspect, all members in the group are suspects.
However, they find that it is not easy to identify all the suspects when a student is recognized as a suspect. Your job is to write a program which finds all the suspects.Input
A case with n = 0 and m = 0 indicates the end of the input, and need not be processed.
Output
Sample Input
100 4 2 1 2 5 10 13 11 12 14 2 0 1 2 99 2 200 2 1 5 5 1 2 3 4 5 1 0 0 0
Sample Output
4 1 1
#include"stdio.h" #include"cstdio" #include"algorithm" #include"string.h" const int max_n=3*(1e4)+50; int par[max_n],rank[max_n]; void init(int a) { par[a]=a; rank[a]=0; } int find(int x) { if(par[x]==x) return x; else return par[x]=find(par[x]); } void unite(int x,int y) { x=find(x); y=find(y); if(x==y) return ; if(rank[x]<rank[y]) par[x]=y; else par[y]=x; if(rank[x]=rank[y]) rank[x]++; } int main() { int i,a,n,m,k,t,x; while(scanf("%d%d",&n,&m)!=EOF) { if(m==0&&n==0) break; for(i=0;i<=n;i++) init(i); memset(rank,0,sizeof(rank)); while(m--) { scanf("%d",&k); k--; scanf("%d",&a); a=find(a); while(k--) { scanf("%d",&x); unite(a,x); } } int ans=0;t=find(0); for(i=0;i<n;i++) { if(t==find(i)) ans++; } printf("%d\n",ans); } }
E - Mike and Chocolate Thieves
Bad news came to Mike's village, some thieves stole a bunch of chocolates from the local factory! Horrible!
Aside from loving sweet things, thieves from this area are known to be very greedy. So after a thief takes his number of chocolates for himself, the next thief will take exactly k times more than the previous one. The value of k (k > 1) is a secret integer known only to them. It is also known that each thief's bag can carry at most n chocolates (if they intend to take more, the deal is cancelled) and that there were exactly four thieves involved.
Sadly, only the thieves know the value of n, but rumours say that the numbers of ways they could have taken the chocolates (for a fixed n, but not fixed k) is m. Two ways are considered different if one of the thieves (they should be numbered in the order they take chocolates) took different number of chocolates in them.
Mike want to track the thieves down, so he wants to know what their bags are and value of n will help him in that. Please find the smallest possible value of n or tell him that the rumors are false and there is no such n.
Input
The single line of input contains the integer m (1 ≤ m ≤ 1015) — the number of ways the thieves might steal the chocolates, as rumours say.
Output
Print the only integer n — the maximum amount of chocolates that thieves' bags can carry. If there are more than one n satisfying the rumors, print the smallest one.
If there is no such n for a false-rumoured m, print - 1.
Example
1
8
8
54
10
-1
Note
In the first sample case the smallest n that leads to exactly one way of stealing chocolates is n = 8, whereas the amounts of stealed chocolates are (1, 2, 4, 8) (the number of chocolates stolen by each of the thieves).
In the second sample case the smallest n that leads to exactly 8 ways is n = 54 with the possibilities: (1, 2, 4, 8), (1, 3, 9, 27), (2, 4, 8, 16), (2, 6, 18, 54), (3, 6, 12, 24), (4, 8, 16, 32), (5, 10, 20, 40), (6, 12, 24, 48).
There is no n leading to exactly 10 ways of stealing chocolates in the third sample case.
#include"stdio.h" #include"cstdio" #include"algorithm" typedef long long ll; using namespace std; ll max_n=1e16; ll ef(ll mid) { ll i,sum=0; for(i=2;i*i*i<=mid;i++) { sum+=mid/(i*i*i); } return sum; } int main() { ll i,L,R,n,m,ret=0; L=0;R=max_n; scanf("%lld",&n); ll mid; while(L<=R) { mid=(L+R)>>1; m=ef(mid); if(m<n) L=mid+1; else if(m>n) R=mid-1; else break; } if(m==n) { for(i=2;i*i*i<=mid;i++) { ret=max(ret,mid/(i*i*i)*i*i*i); } printf("%lld\n",ret); } else printf("-1\n"); }
F - String Game
Little Nastya has a hobby, she likes to remove some letters from word, to obtain another word. But it turns out to be pretty hard for her, because she is too young. Therefore, her brother Sergey always helps her.
Sergey gives Nastya the word t and wants to get the word p out of it. Nastya removes letters in a certain order (one after another, in this order strictly), which is specified by permutation of letters' indices of the word t: a1... a|t|. We denote the length of word x as |x|. Note that after removing one letter, the indices of other letters don't change. For example, if t = "nastya" and a = [4, 1, 5, 3, 2, 6] then removals make the following sequence of words "nastya" "nastya"
"nastya"
"nastya"
"nastya"
"nastya"
"nastya".
Sergey knows this permutation. His goal is to stop his sister at some point and continue removing by himself to get the word p. Since Nastya likes this activity, Sergey wants to stop her as late as possible. Your task is to determine, how many letters Nastya can remove before she will be stopped by Sergey.
It is guaranteed that the word p can be obtained by removing the letters from word t.
Input
The first and second lines of the input contain the words t and p, respectively. Words are composed of lowercase letters of the Latin alphabet (1 ≤ |p| < |t| ≤ 200 000). It is guaranteed that the word p can be obtained by removing the letters from word t.
Next line contains a permutation a1, a2, ..., a|t| of letter indices that specifies the order in which Nastya removes letters of t (1 ≤ ai ≤ |t|, all ai are distinct).
Output
Print a single integer number, the maximum number of letters that Nastya can remove.
Example
ababcba
abb
5 3 4 1 7 6 2
3
bbbabb
bb
1 6 3 4 2 5
4
Note
In the first sample test sequence of removing made by Nastya looks like this:
"ababcba" "ababcba"
"ababcba"
"ababcba"
Nastya can not continue, because it is impossible to get word "abb" from word "ababcba".
So, Nastya will remove only three letters.
G - Farey
题目传送门题目传送门 (http://acm.uestc.edu.cn/images/assets/1425.pdf
)

浙公网安备 33010602011771号