11/24 PAT(甲级)训练二

单词组:
  1. real number 实数
  2. decimal place 小数点位数
  3. be rounded down 四舍五入
  4. alphabetical 字母顺序的
  5. one-way 单向
  6. identical 相同的
题型.1.字符串处理 2.模拟题 3.完全二叉树4.最短路

1108 Finding Average (20 分)

The basic task is simple: given N real numbers, you are supposed to calculate their average. But what makes it complicated is that some of the input numbers might not be legal. A legal input is a real number in [−1000,1000] and is accurate up to no more than 2 decimal places. When you calculate the average, those illegal numbers must not be counted in.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤100). Then N numbers are given in the next line, separated by one space.

Output Specification:

For each illegal input number, print in a line ERROR: X is not a legal number where X is the input. Then finally print in a line the result: The average of K numbers is Y where K is the number of legal inputs and Y is their average, accurate to 2 decimal places. In case the average cannot be calculated, output Undefined instead of Y. In case K is only 1, output The average of 1 number is Y instead.

Sample Input 1:

7
5 -3.2 aaa 9999 2.3.4 7.123 2.35

Sample Output 1:

ERROR: aaa is not a legal number
ERROR: 9999 is not a legal number
ERROR: 2.3.4 is not a legal number
ERROR: 7.123 is not a legal number
The average of 3 numbers is 1.38

Sample Input 2:

2
aaa -9999

Sample Output 2:

ERROR: aaa is not a legal number
ERROR: -9999 is not a legal number
The average of 0 numbers is Undefined

将字符串转浮点,方便的写法
sscanf(a,"%lf",&temp),传输格式从左往右,sprintf(b,"%.2f",temp),传输格式从右往左
//类似scanf与printf
容易出错的地方,1个数时,输出的是number,0个数是numbers,注意下单词的单复数/(ㄒoㄒ)/~~

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <stack>
using namespace std;
const int MAX=1050;
const int INF=0x3f3f3f3f;
int n,cnt=0;
double ans=0,temp;
char a[MAX],b[MAX];
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        int flag=1;
        scanf("%s",a);
        sscanf(a,"%lf",&temp);
        sprintf(b,"%.2f",temp);
        for(int j=0;j<strlen(a);j++)
       {
           if(a[j]!=b[j])
           {
               flag=0;
               break;
           }
       }
       if(flag==0||temp<-1000||temp>1000)
       {
           cout<<"ERROR: "<<a<<" is not a legal number"<<endl;
       }
       else
       {
           ans+=temp;
           cnt++;
       }
    }
    if(cnt==1)
        printf("The average of 1 number is %.2f\n",ans);
    else if(cnt!=0&&cnt!=1)
    printf("The average of %d numbers is %.2f\n",cnt,ans/cnt);
    else
    printf("The average of 0 numbers is Undefined\n");
   return 0;
}

1109 Group Photo (25 分)

Formation is very important when taking a group photo. Given the rules of forming K rows with N people as the following:The number of people in each row must be N/K (round down to the nearest integer), with all the extra people (if any) standing in the last row;All the people in the rear row must be no shorter than anyone standing in the front rows;In each row, the tallest one stands at the central position (which is defined to be the position (m/2+1), where m is the total number of people in that row, and the division result must be rounded down to the nearest integer);In each row, other people must enter the row in non-increasing order of their heights, alternately taking their positions first to the right and then to the left of the tallest one (For example, given five people with their heights 190, 188, 186, 175, and 170, the final formation would be 175, 188, 190, 186, and 170. Here we assume that you are facing the group so your left-hand side is the right-hand side of the one at the central position.);When there are many people having the same height, they must be ordered in alphabetical (increasing) order of their names, and it is guaranteed that there is no duplication of names.

Now given the information of a group of people, you are supposed to write a program to output their formation.

Input Specification:

Each input file contains one test case. For each test case, the first line contains two positive integers N (≤10^​4​​ ), the total number of people, and K (≤10), the total number of rows. Then N lines follow, each gives the name of a person (no more than 8 English letters without space) and his/her height (an integer in [30, 300]).

Output Specification:

For each case, print the formation – that is, print the names of people in K lines. The names must be separated by exactly one space, but there must be no extra space at the end of each line. Note: since you are facing the group, people in the rear rows must be printed above the people in the front rows.

Sample Input:

10 3
Tom 188
Mike 170
Eva 168
Tim 160
Joe 190
Ann 168
Bob 175
Nick 186
Amy 160
John 159

Sample Output:

Bob Tom Joe Nick
Ann Mike Eva
Tim Amy John

模拟时注意下标从0开始,中间的值为temp[m/2]而不是temp[m/2+1],给左右分别赋值, 第一行个数为m=n-n/k*(k-1)

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <stack>
using namespace std;
const int MAX=10500;
const int INF=0x3f3f3f3f;
struct node
{
    string name;
    int height;
}Node[MAX];
map<int,string>temp;
bool cmp(node a,node b)
{
    if(a.height!=b.height)
    {
        return a.height>b.height;
    }
    else
    {
        return a.name<b.name;
    }
}
int main()
{
    int n,k,m;
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++)
    {
      cin>>Node[i].name>>Node[i].height;
    }
    sort(Node,Node+n,cmp);
    int ans=0,row=k;
    while(row)
    {
        if(row==k)
            m=n-n/k*(k-1);
        else
            m=n/k;
        temp[m/2]=Node[ans].name;
        int j=m/2-1;
        for(int i=1+ans;i<m+ans;i=i+2)
        {
            temp[j--]=Node[i].name;
        }
            j=m/2+1;
        for(int i=2+ans;i<m+ans;i=i+2)
        {
            temp[j++]=Node[i].name;
        }
        cout<<temp[0];
        for(int i=1;i<m;i++)
        {
            cout<<" "<<temp[i];
        }
        cout<<endl;
        ans+=m;
        row--;
    }
   return 0;
}

1110 Complete Binary Tree (25 分)

Given a tree, you are supposed to tell if it is a complete binary tree.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤20) which is the total number of nodes in the tree – and hence the nodes are numbered from 0 to N−1. Then N lines follow, each corresponds to a node, and gives the indices of the left and right children of the node. If the child does not exist, a - will be put at the position. Any pair of children are separated by a space.

Output Specification:

For each case, print in one line YES and the index of the last node if the tree is a complete binary tree, or NO and the index of the root if not. There must be exactly one space separating the word and the number.

Sample Input 1:

9
7 8
- -
- -
- -
0 1
2 3
4 5
- -
- -

Sample Output 1:

YES 8

Sample Input 2:

8
- -
4 5
0 6
- -
2 3
- 7
- -
- -

Sample Output 2:

NO 1

完全二叉树的性质,对于其任何一个结点(编号为x),左子树编号2x,右子树2x+1,遍历的时候更新最大的结点,这题磨了许久,因为m的范围是有可能两位数的,开始一直当一位数,用char-'0’来做就错的,这里字符串最好直接用string来存储。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <stack>
using namespace std;
const int MAX=150;
const int INF=0x3f3f3f3f;
struct node
{
    int lchild,rchild;
}Node[MAX];
int book[MAX];
int n,last,MAX_index=0;
void preorder(int x,int index)
{
    if(x==-1)
        return ;
    if(index>MAX_index)
    {
        MAX_index=index;
        last=x;
    }
    preorder(Node[x].lchild,index*2);
    preorder(Node[x].rchild,index*2+1);
}
int change(char a[])
{
    int sum=0;
    for(int i=0;i<strlen(a);i++)
    {
        sum=sum*10+(a[i]-'0');
    }
    return sum;
}
int main()
{
    char a[22],b[22];
    scanf("%d",&n);
    memset(book,0,sizeof(book));
    getchar();
    for(int i=0;i<n;i++)
    {
        scanf("%s %s",&a,&b);
        if(a[0]!='-')
        {
           Node[i].lchild=change(a);
           book[change(a)]=1;
        }
        else
        {
           Node[i].lchild=-1;
        }
        if(b[0]!='-')
        {
            Node[i].rchild=change(b);
            book[change(b)]=1;
        }
        else
        {
            Node[i].rchild=-1;
        }
        getchar();
    }
    int i;
    for(i=0;i<n;i++)
    {
        if(book[i]==0)
            break;
    }
    preorder(i,1);
    if(MAX_index==n)
    {
        printf("YES %d\n",last);
    }
    else
    {
        printf("NO %d\n",i);
    }
   return 0;
}

1111 Online Map (30 分)

Input our current position and a destination, an online map can recommend several paths. Now your job is to recommend two paths to your user: one is the shortest, and the other is the fastest. It is guaranteed that a path exists for any request.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers N (2≤N≤500), and M, being the total number of streets intersections on a map, and the number of streets, respectively. Then M lines follow, each describes a street in the format:V1 V2 one-way length time
where V1 and V2 are the indices (from 0 to N−1) of the two ends of the street; one-way is 1 if the street is one-way from V1 to V2, or 0 if not; length is the length of the street; and time is the time taken to pass the street.
Finally a pair of source and destination is given.

Output Specification:

For each case, first print the shortest path from the source to the destination with distance D in the format:

Distance = D: source -> v1 -> … -> destination

Then in the next line print the fastest path with total time T:

Time = T: source -> w1 -> … -> destination

In case the shortest path is not unique, output the fastest one among the shortest paths, which is guaranteed to be unique. In case the fastest path is not unique, output the one that passes through the fewest intersections, which is guaranteed to be unique.
In case the shortest and the fastest paths are identical, print them in one line in the format:

Distance = D; Time = T: source -> u1 -> … -> destination

Sample Input 1:

10 15
0 1 0 1 1
8 0 0 1 1
4 8 1 1 1
3 4 0 3 2
3 9 1 4 1
0 6 0 1 1
7 5 1 2 1
8 5 1 2 1
2 3 0 2 2
2 1 1 1 1
1 3 0 3 1
1 4 0 1 1
9 7 1 3 1
5 1 0 5 2
6 5 1 1 2
3 5

Sample Output 1:

Distance = 6: 3 -> 4 -> 8 -> 5
Time = 3: 3 -> 1 -> 5

Sample Input 2:

7 9
0 4 1 1 1
1 6 1 1 3
2 6 1 1 1
2 5 1 2 2
3 0 0 1 1
3 1 1 1 3
3 2 1 1 2
4 5 0 2 2
6 5 1 1 2
3 5

Sample Output 2:

Distance = 3; Time = 4: 3 -> 2 -> 5

用两次dijkstra。思路蛮简单,代码写的繁琐,代码一长,有好几个地方不小心写错了,
( * ^ _ ^ * )
第一处 :在第二段的dfs2里去调用第一段的dfs???
第二处 :卧槽检查出来笑了许久,这磕碜的!!
在这里插入图片描述
第三处:压缩路径时候有个标尺忘记加了????瘪忘记了呀( = _ = )

if(dis[v]>dis[u]+G[u][v])
      {
                    dis[v]=dis[u]+G[u][v];
                    c[v]=c[u]+cost[u][v];//测试点7分
                    pre[v]=u;
      }
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <stack>
using namespace std;
const int MAX=550;
const int INF=0x3f3f3f3f;
int n,m;
int G[MAX][MAX];
int cost[MAX][MAX];
int dis[MAX*MAX],c[MAX*MAX],book[MAX],pre[MAX],pre2[MAX],num[MAX];
int st,se;
vector<int>path1,path2;
void dijkstra(int start)
{
    memset(book,0,sizeof(book));
    fill(dis,dis+MAX,INF);
    fill(c,c+MAX,INF);
    dis[start]=0;
    c[start]=0;
    for(int i=0;i<n;i++)
    {
        pre[i]=i;
    }
    for(int i=0;i<n;i++)
    {
        int u=-1,MIN=INF;
        for(int j=0;j<n;j++)
        {
            if(book[j]==0&&dis[j]<MIN)
            {
                u=j;
                MIN=dis[j];
            }
        }
        if(u==-1)
            return ;
        book[u]=1;
        for(int v=0;v<n;v++)
        {
            if(book[v]==0&&G[u][v]!=INF)
            {
                if(dis[v]>dis[u]+G[u][v])
                {
                    dis[v]=dis[u]+G[u][v];
                    c[v]=c[u]+cost[u][v];//测试点7分
                    pre[v]=u;
                }
                else if(dis[v]==dis[u]+G[u][v])
                {
                    if(c[v]>c[u]+cost[u][v])
                    {
                        c[v]=c[u]+cost[u][v];
                        pre[v]=u;
                    }
                }
            }
        }
    }
}
void dijkstra2(int start)
{
    memset(book,0,sizeof(book));
    fill(c,c+MAX,INF);
    memset(num,0,sizeof(num));
    c[start]=0;
    num[start]=1;
    for(int i=0;i<n;i++)
    {
        pre2[i]=i;
    }
    for(int i=0;i<n;i++)
    {
        int u=-1,MIN=INF;
        for(int j=0;j<n;j++)
        {
            if(book[j]==0&&c[j]<MIN)
            {
                u=j;
                MIN=c[j];
            }
        }
        if(u==-1)
            return ;
        book[u]=1;
        for(int v=0;v<n;v++)
        {
            if(book[v]==0&&cost[u][v]!=INF)
            {
                if(c[v]>c[u]+cost[u][v])
                {
                    c[v]=c[u]+cost[u][v];
                    num[v]=num[u]+1;
                    pre2[v]=u;
                }
                else if(c[v]==c[u]+cost[u][v])
                {
                    int numv=num[v];
                    int numu=num[u]+1;
                    if(numu<numv)
                    {
                        num[v]=num[u]+1;
                        pre2[v]=u;
                    }
                }
            }
        }
    }
}
void dfs(int v)
{
    if(v==st)
    {
        path1.push_back(st);
        return;
    }
    dfs(pre[v]);
    path1.push_back(v);
}
void dfs2(int v)
{
    if(v==st)
    {
        path2.push_back(st);
        return;
    }
    dfs2(pre2[v]);
    path2.push_back(v);
}
int main()
{
    int flag=0;
    scanf("%d%d",&n,&m);
    fill(G[0],G[0]+MAX*MAX,INF);
    fill(cost[0],cost[0]+MAX*MAX,INF);
    for(int i=0;i<m;i++)
    {
        int x,y,ow,dis,time;
        scanf("%d%d%d%d%d",&x,&y,&ow,&dis,&time);
        if(ow==0)
      {
        G[x][y]=G[y][x]=dis;
        cost[x][y]=cost[y][x]=time;
      }
        else
        {
            G[x][y]=dis;
            cost[x][y]=time;
        }
    }
    scanf("%d%d",&st,&se);
    dijkstra(st);
    dfs(se);
    dijkstra2(st);
    dfs2(se);
    for(int i=0;i<min(path1.size(),path2.size());i++)
    {
        if(path1[i]!=path2[i])
        {
                flag=1;
                break;
        }
    }
    if(flag==0)
    {
       printf("Distance = %d; ",dis[se]);
       printf("Time = %d: ",c[se]);
       for(int i=0;i<path1.size();i++)
       {
           if(i!=0)
           {
               printf(" -> ");
           }
           printf("%d",path1[i]);
       }
    }
    else if(flag==1)
    {
       printf("Distance = %d: ",dis[se]);
       for(int i=0;i<path1.size();i++)
       {
           if(i!=0)
           {
               printf(" -> ");
           }
           printf("%d",path1[i]);
       }
       printf("\n");
       printf("Time = %d: ",c[se]);
       for(int i=0;i<path2.size();i++)
       {
           if(i!=0)
           {
               printf(" -> ");
           }
            printf("%d",path2[i]);
       }
    }
   return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值