C++——USACO Section 3.1 题解

来源:互联网 发布:pla算法 matlab 编辑:程序博客网 时间:2024/04/30 15:59
Agri-Net
Russ Cox

Farmer John has been elected mayor of his town! One of his campaign promises was to bring internet connectivity to all farms in the area. He needs your help, of course.

Farmer John ordered a high speed connection for his farm and is going to share his connectivity with the other farmers. To minimize cost, he wants to lay the minimum amount of optical fiber to connect his farm to all the other farms.

Given a list of how much fiber it takes to connect each pair of farms, you must find the minimum amount of fiber needed to connect them all together. Each farm must connect to some other farm such that a packet can flow from any one farm to any other farm.

The distance between any two farms will not exceed 100,000.

PROGRAM NAME: agrinet

INPUT FORMAT

Line 1:The number of farms, N (3 <= N <= 100).Line 2..end:The subsequent lines contain the N x N connectivity matrix, where each element shows the distance from on farm to another. Logically, they are N lines of N space-separated integers. Physically, they are limited in length to 80 characters, so some lines continue onto others. Of course, the diagonal will be 0, since the distance from farm i to itself is not interesting for this problem.

SAMPLE INPUT (file agrinet.in)

40 4 9 214 0 8 179 8 0 1621 17 16 0

OUTPUT FORMAT

The single output contains the integer length that is the sum of the minimum length of fiber required to connect the entire set of farms.

SAMPLE OUTPUT (file agrinet.out)

28

/*ID: mcdonne1PROG: agrinetLANG: C++*/#include<cstdio>bool u[1001];int minn[1001],g[1001][1001];int main(){freopen("agrinet.in","r",stdin);freopen("agrinet.out","w",stdout);int n;scanf("%d",&n);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&g[i][j]);for(int i=0;i<=1000;i++) minn[i]=100000000;minn[1]=0;for(int i=0;i<=1000;i++) u[i]=true;for(int i=1;i<=n;i++){register int k=0;for(int j=1;j<=n;j++) if(u[j]==true&&minn[j]<minn[k]) k=j;u[k]=false;for(int j=1;j<=n;j++) if(u[j]==true&&g[k][j]<minn[j]) minn[j]=g[k][j];}int total=0;for(int i=1;i<=n;i++) total=total+minn[i];printf("%d\n",total);return 0;}

Score Inflation

The more points students score in our contests, the happier we here at the USACO are. We try to design our contests so that people can score as many points as possible, and would like your assistance.

We have several categories from which problems can be chosen, where a "category" is an unlimited set of contest problems which all require the same amount of time to solve and deserve the same number of points for a correct solution. Your task is write a program which tells the USACO staff how many problems from each category to include in a contest so as to maximize the total number of points in the chosen problems while keeping the total solution time within the length of the contest.

The input includes the length of the contest, M (1 <= M <= 10,000) (don't worry, you won't have to compete in the longer contests until training camp) and N, the number of problem categories, where 1 <= N <= 10,000.

Each of the subsequent N lines contains two integers describing a category: the first integer tells the number of points a problem from that category is worth (1 <= points <= 10000); the second tells the number of minutes a problem from that category takes to solve (1 <= minutes <= 10000).

Your program should determine the number of problems we should take from each category to make the highest-scoring contest solvable within the length of the contest. Remember, the number from any category can be any nonnegative integer (0, one, or many). Calculate the maximum number of possible points.

PROGRAM NAME: inflate

INPUT FORMAT

Line 1:M, N -- contest minutes and number of problem classesLines 2-N+1:Two integers: the points and minutes for each class

SAMPLE INPUT (file inflate.in)

300 4100 60250 120120 10035 20

OUTPUT FORMAT

A single line with the maximum number of points possible given the constraints.

SAMPLE OUTPUT (file inflate.out)

605
(Take two problems from #2 and three from #4.) 
/*ID: mcdonne1PROG: inflateLANG: C++*/#include<cstdio>#include<algorithm>using namespace std;int m,n;int time[10001],score[10001];int f[10001]={1};int main(){freopen("inflate.in","r",stdin);freopen("inflate.out","w",stdout);scanf("%d%d",&m,&n);for(int i=1;i<=n;++i) scanf("%d%d",&score[i],&time[i]);for(int i=1;i<=n;++i)for(int j=time[i];j<=m;++j)if(f[j-time[i]])f[j]=max(f[j],f[j-time[i]]+score[i]);sort(f,f+1+m);printf("%d\n",f[m]-1);return 0;}
Humble Numbers

For a given set of K prime numbers S = {p1, p2, ..., pK}, consider the set of all numbers whose prime factors are a subset of S. This set contains, for example, p1, p1p2, p1p1, and p1p2p3 (among others). This is the set of `humble numbers' for the input set S. Note: The number 1 is explicitly declared not to be a humble number.

Your job is to find the Nth humble number for a given set S. Long integers (signed 32-bit) will be adequate for all solutions.

PROGRAM NAME: humble

INPUT FORMAT

Line 1:Two space separated integers: K and N, 1 <= K <=100 and 1 <= N <= 100,000.Line 2:K space separated positive integers that compose the set S.

SAMPLE INPUT (file humble.in)

4 192 3 5 7

OUTPUT FORMAT

The Nth humble number from set S printed alone on a line.

SAMPLE OUTPUT (file humble.out)

27
/*ID: mcdonne1PROG: humbleLANG: C++*/#include<cstdio>int n,k,now;int a[100001],ans[100001]={1},s[100001];inline int min(int a,int b){return a < b ? a : b ;}int main(){freopen("humble.in","r",stdin);freopen("humble.out","w",stdout);scanf("%d%d",&n,&k);for(int i=1;i<=n;++i) scanf("%d",&a[i]);for(int i=1;i<=k;++i){now=0x7fffffff;for(int j=1;j<=n;++j){while(a[j]*ans[s[j]]<=ans[i-1]) s[j]++;now=min(now,a[j]*ans[s[j]]);}ans[i]=now;}printf("%d\n",ans[k]);return 0;}
Contact
IOI'98

The cows have developed a new interest in scanning the universe outside their farm with radiotelescopes. Recently, they noticed a very curious microwave pulsing emission sent right from the centre of the galaxy. They wish to know if the emission is transmitted by some extraterrestrial form of intelligent life or if it is nothing but the usual heartbeat of the stars.

Help the cows to find the Truth by providing a tool to analyze bit patterns in the files they record. They are seeking bit patterns of length A through B inclusive (1 <= A <= B <= 12) that repeat themselves most often in each day's data file. They are looking for the patterns that repeat themselves most often. An input limit tells how many of the most frequent patterns to output.

Pattern occurrences may overlap, and only patterns that occur at least once are taken into account.

PROGRAM NAME: contact

INPUT FORMAT

Line 1:Three space-separated integers: A, B, N; (1 <= N ≤ 50)Lines 2 and beyond:A sequence of as many as 200,000 characters, all 0 or 1; the characters are presented 80 per line, except potentially the last line.

SAMPLE INPUT (file contact.in)

2 4 1001010010010001000111101100001010011001111000010010011110010000000

In this example, pattern 100 occurs 12 times, and pattern 1000 occurs 5 times. The most frequent pattern is 00, with 23 occurrences.

OUTPUT FORMAT

Lines that list the N highest frequencies (in descending order of frequency) along with the patterns that occur in those frequencies. Order those patterns by shortest-to-longest and increasing binary number for those of the same frequency. If fewer than N highest frequencies are available, print only those that are.

Print the frequency alone by itself on a line. Then print the actual patterns space separated, six to a line (unless fewer than six remain).

SAMPLE OUTPUT (file contact.out)

23001501 10121001111 000 001100108010070010 10016111 00005011 110 100040001 0011 1100
/*ID: mcdonne1PROG: contactLANG: C++*/#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int a,b,n,cnt;int time[20][5000];char s[200005];struct node{int time,v,len;}e[100000];inline int gain(int e,int len){int ans=0;for(int i=0;i<len;++i)ans=ans*2+(s[e+i]=='1');return ans;}inline void print(int v,int len){char s[20]="";for(int i=len-1;i>=0;--i){s[i]=v%2+'0';v/=2;}printf("%s",s);}inline bool cmp(node a,node b){return a.time > b.time || a.time == b.time && (a.len < b.len || a.len == b.len && a.v < b.v);}int main(){freopen("contact.in","r",stdin);freopen("contact.out","w",stdout);scanf("%d%d%d",&a,&b,&n);while(~scanf("%s",s+strlen(s)));int l=strlen(s);for(int i=0;i<l-a+1;++i)for(int j=a;j<=b&&i+j<=l;++j)++time[j][gain(i,j)];for(int i=a;i<=b;++i)for(int j=0;j<1<<i;++j)if(time[i][j])e[cnt++]=(node){time[i][j],j,i};sort(e,e+cnt,cmp);int num;for(int i=0,j=0;i<cnt;++i){if(!i||e[i].time!=e[i-1].time){++j;if(j>n) break;printf("%d\n",e[i].time);num=0;}print(e[i].v,e[i].len);++num;e[i].time==e[i+1].time&&num%6 ? putchar(' ') : putchar('\n');}return 0;}
Stamps

Given a set of N stamp values (e.g., {1 cent, 3 cents}) and an upper limit K to the number of stamps that can fit on an envelope, calculate the largest unbroken list of postages from 1 cent to M cents that can be created.

For example, consider stamps whose values are limited to 1 cent and 3 cents; you can use at most 5 stamps. It's easy to see how to assemble postage of 1 through 5 cents (just use that many 1 cent stamps), and successive values aren't much harder:

  • 6 = 3 + 3
  • 7 = 3 + 3 + 1
  • 8 = 3 + 3 + 1 + 1
  • 9 = 3 + 3 + 3
  • 10 = 3 + 3 + 3 + 1
  • 11 = 3 + 3 + 3 + 1 + 1
  • 12 = 3 + 3 + 3 + 3
  • 13 = 3 + 3 + 3 + 3 + 1.

However, there is no way to make 14 cents of postage with 5 or fewer stamps of value 1 and 3 cents. Thus, for this set of two stamp values and a limit of K=5, the answer is M=13.

The most difficult test case for this problem has a time limit of 3 seconds.

PROGRAM NAME: stamps

INPUT FORMAT

Line 1:Two integers K and N. K (1 <= K <= 200) is the total number of stamps that can be used. N (1 <= N <= 50) is the number of stamp values.Lines 2..end:N integers, 15 per line, listing all of the N stamp values, each of which will be at most 10000.

SAMPLE INPUT (file stamps.in)

5 21 3

OUTPUT FORMAT

Line 1:One integer, the number of contiguous postage values starting at 1 cent that can be formed using no more than K stamps from the set.

SAMPLE OUTPUT (file stamps.out)

13
/*ID: mcdonne1PROG: stampsLANG: C++*/#include<cstdio>#include<algorithm>#define min(a,b) (a)<(b)?(a):(b)int k,n;int val[51],used[2000100];bool f[2000100];int main(){freopen("stamps.in","r",stdin);freopen("stamps.out","w",stdout);scanf("%d%d",&k,&n);for(int i=1;i<=n;++i) scanf("%d",&val[i]);std::sort(val+1,val+1+n);f[0]=true;for(int i=1;i<=n;++i)for(int j=val[i];j<=k*val[n];++j)if(f[j-val[i]]){f[j] ? used[j]=min(used[j],used[j-val[i]]+1) : used[j]=used[j-val[i]]+1;f[j]=true;}for(int i=1;;++i)if(!f[i]||used[i]>k){printf("%d\n",i-1);return 0;}}

原创粉丝点击