PAT 解题报告

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

PAT 1070

基础贪心

Mooncake (25)

时间限制
100 ms
内存限制
32000 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

Mooncake is a Chinese bakery product traditionally eaten during the Mid-Autumn Festival. Many types of fillings and crusts can be found in traditional mooncakes according to the region's culture. Now given the inventory amounts and the prices of all kinds of the mooncakes, together with the maximum total demand of the market, you are supposed to tell the maximum profit that can be made.

Note: partial inventory storage can be taken. The sample shows the following situation: given three kinds of mooncakes with inventory amounts being 180, 150, and 100 thousand tons, and the prices being 7.5, 7.2, and 4.5 billion yuans. If the market demand can be at most 200 thousand tons, the best we can do is to sell 150 thousand tons of the second kind of mooncake, and 50 thousand tons of the third kind. Hence the total profit is 7.2 + 4.5/2 = 9.45 (billion yuans).

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers N (<=1000), the number of different kinds of mooncakes, and D (<=500 thousand tons), the maximum total demand of the market. Then the second line gives the positive inventory amounts (in thousand tons), and the third line gives the positive prices (in billion yuans) of N kinds of mooncakes. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the maximum profit (in billion yuans) in one line, accurate up to 2 decimal places.

Sample Input:
3 200180 150 1007.5 7.2 4.5
Sample Output:
9.45

#include <iostream>#include <algorithm>#include <stdio.h>#include "stdlib.h"#include <string.h>#include <functional>#include <memory.h>using namespace std;#define N 1010#define min(a,b) a>b?b:astruct P{ double cap; double price; double perprice; bool operator < (const P & A) const {  return perprice>A.perprice; }}Moon[N];int main()int n,cap,i; while(cin>>n>>cap) {  for(i=0;i<n;i++)   cin>>Moon[i].cap;  for(i=0;i<n;i++)   cin>>Moon[i].price;  for(i=0;i<n;i++)   Moon[i].perprice = Moon[i].price/Moon[i].cap;  sort(Moon, Moon+n);  double sum = 0;  int i = 0;  while(cap>0&&i<=n)  {   int v = min(cap,Moon[i].cap);   sum += v*Moon[i].perprice;   cap -= v;   i++;  }  printf("%.2f\n",sum); } return 0;}


PAT 1071

字符串处理+map

Speech Patterns (25)

时间限制
300 ms
内存限制
32000 kB
代码长度限制
16000 B
判题程序
Standard
作者
HOU, Qiming

People often have a preference among synonyms of the same word. For example, some may prefer "the police", while others may prefer "the cops". Analyzing such patterns can help to narrow down a speaker's identity, which is useful when validating, for example, whether it's still the same person behind an online avatar.

Now given a paragraph of text sampled from someone's speech, can you find the person's most commonly used word?

Input Specification:

Each input file contains one test case. For each case, there is one line of text no more than 1048576 characters in length, terminated by a carriage return '\n'. The input contains at least one alphanumerical character, i.e., one character from the set [0-9 A-Z a-z].

Output Specification:

For each test case, print in one line the most commonly occurring word in the input text, followed by a space and the number of times it has occurred in the input. If there are more than one such words, print the lexicographically smallest one. The word should be printed in all lower case. Here a "word" is defined as a continuous sequence of alphanumerical characters separated by non-alphanumerical characters or the line beginning/end.

Note that words are case insensitive.

Sample Input:
Can1: "Can a can can a can?  It can!"
Sample Output:
can 5


#include"iostream"#include "string"#include"map"#include"algorithm"using namespace std;#define N 1000bool isalp(char a)if(a>='a'&&a<='z'||a>='A'&&a<='Z'||a>='0'&&a<='9')  return truereturn false;}int main()string str,word; map<string,int> Count;//notice it's better not substitute 'string' to 'char*', for char* stores the address while string stores object map<string,int>::iterator it,tmp; while(getline(cin,str)) {  transform(str.begin(),str.end(),str.begin(),::tolower);  //cout<<str<<endl;  int i=0,j;  while(i<str.length())  {   j = i;   while(!isalp(str[j])&&j<str.length())j++;//skip non-alphanumerical character   i = j;   while(isalp(str[j])&&i<str.length())j++; //i is the start and j is the end point   if(i!=j)   {    string word=str.substr(i,j-i);//notice the usage of substr: substr(start,length)    if(Count.find(word)==Count.end())     Count[word] = 1;    else     Count[word]++;    i=j;   }  }  int minn = -1;    for(it = Count.begin();it!=Count.end();it++)   if(it->second>minn)   {    minn = it->second;    tmp = it;   }   cout<<tmp->first<<" "<<tmp->second<<endl; } return 0;}




PAT 1072

最短路径+sort (用到一些STL函数)

Gas Station (30)

时间限制
200 ms
内存限制
32000 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

A gas station has to be built at such a location that the minimum distance between the station and any of the residential housing is as far away as possible. However it must guarantee that all the houses are in its service range.

Now given the map of the city and several candidate locations for the gas station, you are supposed to give the best recommendation. If there are more than one solution, output the one with the smallest average distance to all the houses. If such a solution is still not unique, output the one with the smallest index number.

Input Specification:

Each input file contains one test case. For each case, the first line contains 4 positive integers: N (<= 103), the total number of houses; M (<= 10), the total number of the candidate locations for the gas stations; K (<= 104), the number of roads connecting the houses and the gas stations; and DS, the maximum service range of the gas station. It is hence assumed that all the houses are numbered from 1 to N, and all the candidate locations are numbered from G1 to GM.

Then K lines follow, each describes a road in the format
P1 P2 Dist
where P1 and P2 are the two ends of a road which can be either house numbers or gas station numbers, and Dist is the integer length of the road.

Output Specification:

For each test case, print in the first line the index number of the best location. In the next line, print the minimum and the average distances between the solution and all the houses. The numbers in a line must be separated by a space and be accurate up to 1 decimal place. If the solution does not exist, simply output “No Solution”.

Sample Input 1:
4 3 11 51 2 21 4 21 G1 41 G2 32 3 22 G2 13 4 23 G3 24 G1 3G2 G1 1G3 G2 2
Sample Output 1:
G12.0 3.3
Sample Input 2:
2 1 2 101 G1 92 G1 20
Sample Output 2:
No Solution


#include"iostream"#include "string"#include"algorithm"#include"memory.h"#include"numeric"#include "stdlib.h"using namespace std;#define N 1001#define M 12#define INF 10000000double map[N+M][N+M];double dist[N+M];bool visited[N+M];struct Gas{ int idx; double mindis; double averagedis; bool operator < (const Gas & A) const {  if(A.mindis!=mindis)   return mindis>A.mindis;  if(A.averagedis!=averagedis)   return averagedis<A.averagedis;  return idx<A.idx; }}G[M];int str2int(char s[],int n)int i=0if(s[0]=='G')  i=1int sum=i==0?0:n; sum+=atoi(s+i); return sum;}void dijkstra(int source,int n)memset(visited,false,sizeof(visited)); visited[source] = trueint i,j; for(j=1;j<=n;j++)   dist[j] = map[j][source]; dist[source] = 0for(j=0;j<n-1;j++) {  int minn = INF,point;  for(i=1;i<=n;i++)   if(!visited[i] && dist[i]<minn)   {    minn = dist[i];    point = i;   }  visited[point] = true;  for(i=1;i<=n;i++)   if(!visited[i]&&dist[i]>dist[point]+map[point][i])    dist[i] = dist[point]+map[point][i]; }}int main()int n,m,k,r; cin>>n>>m>>k>>r; char str1[5],str2[5]; double dis; int i,j; for(i=1;i<=n+m;i++)  for(j=1;j<=n+m;j++)   map[i][j] = map[j][i] =  INF; while(k--) {  scanf("%s%s%lf",str1,str2,&dis);  int a = str2int(str1,n);  int b = str2int(str2,n);  map[a][b] = map[b][a] = dis; } int n_avaliable = 0for(i=1;i<=m;i++) {  int source = n+i;  dijkstra(source,n+m);  for(j=1;j<=n;j++)   if(dist[j]>r)    break;  if(j==n+1)  {   G[n_avaliable].idx = i;   G[n_avaliable].mindis = *min_element(dist+1,dist+n+1);   G[n_avaliable].averagedis = accumulate(dist+1,dist+n+1,0);   n_avaliable++;  } } if(n_avaliable == 0)  cout<<"No Solution"<<endlelse {  sort(G,G+n_avaliable); //actually we needn't to sort. However, it won't cost much for little m<=10 in this case.  cout<<"G"<<G[0].idx<<endl;  printf("%.1f %.1f\n",G[0].mindis,G[0].averagedis/n); }  return 0;}


PAT 1061

字符串处理(注意边界)

1061. Dating (20)

时间限制
50 ms
内存限制
32000 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

Sherlock Holmes received a note with some strange strings: "Let's date! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm". It took him only a minute to figure out that those strange strings are actually referring to the coded time "Thursday 14:04" -- since the first common capital English letter (case sensitive) shared by the first two strings is the 4th capital letter 'D', representing the 4th day in a week; the second common character is the 5th capital letter 'E', representing the 14th hour (hence the hours from 0 to 23 in a day are represented by the numbers from 0 to 9 and the capital letters from A to N, respectively); and the English letter shared by the last two strings is 's' at the 4th position, representing the 4th minute. Now given two pairs of strings, you are supposed to help Sherlock decode the dating time.

Input Specification:

Each input file contains one test case. Each case gives 4 non-empty strings of no more than 60 characters without white space in 4 lines.

Output Specification:

For each test case, print the decoded time in one line, in the format "DAY HH:MM", where "DAY" is a 3-character abbreviation for the days in a week -- that is, "MON" for Monday, "TUE" for Tuesday, "WED" for Wednesday, "THU" for Thursday, "FRI" for Friday, "SAT" for Saturday, and "SUN" for Sunday. It is guaranteed that the result is unique for each case.

Sample Input:
3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm
Sample Output:
THU 14:04



#include<iostream>#include<string>using namespace std;#define min(a,b) a<b?a:bint main()string str[5]; string day[8] = {"MON","TUE","WED","THU","FRI","SAT","SUN"}; int i,j; for(i=0;i<4;i++) {  cin>>str[i]; } for(i=0;i<min(str[0].length(),str[1].length());i++) {  if(str[0][i]==str[1][i]&&str[0][i]>='A'&&str[0][i]<='G')//notice it is 'G' not 'Z'   break; } int d=str[0][i]-'A';  i++; for(;i<min(str[0].length(),str[1].length());i++) {  if(str[0][i]==str[1][i]&&(str[0][i]>='A'&&str[0][i]<='N'||str[0][i]>='0'&&str[0][i]<='9'))   break; } int h = str[0][i]>'9'?str[0][i]-'A'+10:str[0][i]-'0'for(i=0;i<min(str[2].length(),str[3].length());i++) {  if(str[2][i]==str[3][i]&&(str[2][i]>='a'&&str[2][i]<='z'||str[2][i]>='A'&&str[2][i]<='Z'))   break; } cout<<day[d]<<" "printf("%02d:%02d\n",h,i);}




PAT 1062

排序

1062. Talent and Virtue (25)

时间限制
200 ms
内存限制
32000 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Li

About 900 years ago, a Chinese philosopher Sima Guang wrote a history book in which he talked about people's talent and virtue. According to his theory, a man being outstanding in both talent and virtue must be a "sage(圣人)"; being less excellent but with one's virtue outweighs talent can be called a "nobleman(君子)"; being good in neither is a "fool man(愚人)"; yet a fool man is better than a "small man(小人)" who prefers talent than virtue.

Now given the grades of talent and virtue of a group of people, you are supposed to rank them according to Sima Guang's theory.

Input Specification:

Each input file contains one test case. Each case first gives 3 positive integers in a line: N (<=105), the total number of people to be ranked; L (>=60), the lower bound of the qualified grades -- that is, only the ones whose grades of talent and virtue are both not below this line will be ranked; and H (<100), the higher line of qualification -- that is, those with both grades not below this line are considered as the "sages", and will be ranked in non-increasing order according to their total grades. Those with talent grades below H but virtue grades not are cosidered as the "noblemen", and are also ranked in non-increasing order according to their total grades, but they are listed after the "sages". Those with both grades below H, but with virtue not lower than talent are considered as the "fool men". They are ranked in the same way but after the "noblemen". The rest of people whose grades both pass the L line are ranked after the "fool men".

Then N lines follow, each gives the information of a person in the format:

ID_Number Virtue_Grade Talent_Grade
where ID_Number is an 8-digit number, and both grades are integers in [0, 100]. All the numbers are separated by a space.

Output Specification:

The first line of output must give M (<=N), the total number of people that are actually ranked. Then M lines follow, each gives the information of a person in the same format as the input, according to the ranking rules. If there is a tie of the total grade, they must be ranked with respect to their virtue grades in non-increasing order. If there is still a tie, then output in increasing order of their ID's.

Sample Input:
14 60 8010000001 64 9010000002 90 6010000011 85 8010000003 85 8010000004 80 8510000005 82 7710000006 83 7610000007 90 7810000008 75 7910000009 59 9010000010 88 4510000012 80 10010000013 90 9910000014 66 60
Sample Output:
1210000013 90 9910000012 80 10010000003 85 8010000011 85 8010000004 80 8510000007 90 7810000006 83 7610000005 82 7710000002 90 6010000014 66 6010000008 75 7910000001 64 90

#include<iostream>#include<string>#include"functional"#include"algorithm"using namespace std;#define min(a,b) a<b?a:b#define N 100001struct Peo{ int h; int v; int total; int level; string id; bool operator <(Peo const & A)const {  if(level!=A.level)   return level>A.level;  if(total!=A.total)   return total>A.total;  if(v!=A.v)   return v>A.v;  return id.compare(A.id)<0; }}P[N];int main()int n,l,h; string id; int a,b,level,idx = 0cin>>n>>l>>h; while(n--) {  cin>>id;  scanf("%d%d",&a,&b);  if(a>=l&&b>=l)  {   if(a>=h&&b>=h)    level = 4;   else if(a>=h&&b<h)    level = 3;   else if(a<h && b<h && a>=b)    level = 2;   else    level = 1;   P[idx].v = a;   P[idx].h = b;   P[idx].total = a+b;   P[idx].id=id;   P[idx++].level = level;  } } cout<<idx<<endl; sort(P,P+idx); for(int i = 0;i<idx;i++) {  cout<<P[i].id;  printf(" %d %d\n",P[i].v,P[i].h); } return 0;}


PAT 1063

大数据优化处理(容易超时)

注意点:

1. 50个数组,2000次询问:存结果(见代码中percent数组)

2. 排序,从O(n^2)降到O(nlogn)


1063. Set Similarity (25)

时间限制
300 ms
内存限制
32000 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

Given two sets of integers, the similarity of the sets is defined to be Nc/Nt*100%, where Nc is the number of distinct common numbers shared by the two sets, and Nt is the total number of distinct numbers in the two sets. Your job is to calculate the similarity of any given pair of sets.

Input Specification:

Each input file contains one test case. Each case first gives a positive integer N (<=50) which is the total number of sets. Then N lines follow, each gives a set with a positive M (<=104) and followed by M integers in the range [0, 109]. After the input of sets, a positive integer K (<=2000) is given, followed by K lines of queries. Each query gives a pair of set numbers (the sets are numbered from 1 to N). All the numbers in a line are separated by a space.

Output Specification:

For each query, print in one line the similarity of the sets, in the percentage form accurate up to 1 decimal place.

Sample Input:
33 99 87 1014 87 101 5 877 99 101 18 5 135 18 9921 21 3
Sample Output:
50.0%33.3%


#include<iostream>#include<string>#include<vector>#include"functional"#include"algorithm"using namespace std;#define min(a,b) a<b?a:b#define N 10001#define M 51double percent[M][M];//save the asking result (for faster)int main()int n,tmp,ax,bx,nx; vector<int> a[51],vec; int i,j; scanf("%d",&n); for(j=0;j<n;j++) {  vec.clear();  scanf("%d",&nx);  for(i = 0;i<nx;i++)  {   scanf("%d",&tmp);   if(find(vec.begin(),vec.end(),tmp)==vec.end())    vec.push_back(tmp);  }  sort(vec.begin(),vec.end());  a[j]=vec; } for(i=0;i<n;i++)  for(j=0;j<n;j++)   percent[i][j]=-1cin>>n; while(n--) {  scanf("%d%d",&ax,&bx);  ax--;bx--;  if(percent[ax][bx]!=-1)  {   printf("%.1f%%\n",percent[ax][bx]);   continue;  }  int same=0,distinct=a[ax].size();    int ia=0,ib=0;  int la=a[ax].size(), lb = a[bx].size();  while(ia<la && ib<lb)  {   while(a[ax][ia]<a[bx][ib]&&ia<la)    ia++;   while(a[bx][ib]<a[ax][ia]&&ib<lb)   {    ib++;    distinct++;   }   if(a[ax][ia]==a[bx][ib])   {    ia++,ib++;    same++;   }  }  while(ib<lb)  {   ib++;   distinct++;  }  double perc = 1.0*same/distinct*100.0;  percent[ax][bx]=percent[bx][ax]=perc;  printf("%.1f%%\n",perc); }  return 0;}


PAT 1064

完全二叉树+层次遍历(典型递归)

输入数组从小到大的顺序为“左根右”遍历顺序,因此按前序遍历依次赋值即可。


1064. Complete Binary Search Tree (30)

时间限制
100 ms
内存限制
32000 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

  • The left subtree of a node contains only nodes with keys less than the node's key.
  • The right subtree of a node contains only nodes with keys greater than or equal to the node's key.
  • Both the left and right subtrees must also be binary search trees.

A Complete Binary Tree (CBT) is a tree that is completely filled, with the possible exception of the bottom level, which is filled from left to right.

Now given a sequence of distinct non-negative integer keys, a unique BST can be constructed if it is required that the tree must also be a CBT. You are supposed to output the level order traversal sequence of this BST.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=1000). Then N distinct non-negative integer keys are given in the next line. All the numbers in a line are separated by a space and are no greater than 2000.

Output Specification:

For each test case, print in one line the level order traversal sequence of the corresponding complete binary search tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.

Sample Input:
101 2 3 4 5 6 7 8 9 0
Sample Output:
6 3 8 1 5 7 9 0 2 4

#include<iostream>#include<string>#include<vector>#include"functional"#include"algorithm"using namespace std;#define N 1001int a[N],tree[N];int idx;void LRR(int i,int n)//left->root->right sequenceint l=2*i,r=2*i+1if(i>n)  return; LRR(l,n); //cout<<i<<endl; tree[i]=a[idx++]; if(r<=n)  LRR(r,n);}int main()int n,tmp,i,j; scanf("%d",&n); for(j=0;j<n;j++)  scanf("%d",&a[j]); sort(a,a+n); idx=0; LRR(1,n); for(i=1;i<n;i++)  printf("%d ",tree[i]); printf("%d\n",tree[i]); return 0;}



PAT 1046

小朋友们注意保存中间结果以防超时哦

1046. Shortest Distance (20)

时间限制
100 ms
内存限制
32000 kB
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值