11/25 PAT (甲级) 训练三

单词组:
  1. disjoint 不相交
  2. accurate up 精确到
题型.1.字符串处理 2.送分题 3.并查集 4.BST

1112 Stucked Keyboard (20 分)

On a broken keyboard, some of the keys are always stucked. So when you type some sentences, the characters corresponding to those keys will appear repeatedly on screen for k times. Now given a resulting string on screen, you are supposed to list all the possible stucked keys, and the original string.
Notice that there might be some characters that are typed repeatedly. The stucked key will always repeat output for a fixed k times whenever it is pressed. For example, when k=3, from the string thiiis iiisss a teeeeeest we know that the keys i and e might be stucked, but s is not even though it appears repeatedly sometimes. The original string could be this isss a teest.

Input Specification:

Each input file contains one test case. For each case, the 1st line gives a positive integer k (1<k<=100)which is the output repeating times of a stucked key. The 2nd line contains the resulting string on screen, which consists of no more than 1000 characters from {a-z}, {0-9} and _. It is guaranteed that the string is non-empty.

Output Specification:

For each test case, print in one line the possible stucked keys, in the order of being detected. Make sure that each key is printed once only. Then in the next line print the original string. It is guaranteed that there is at least one stucked key.

Sample Input:

3 caseee1__thiiis_iiisss_a_teeeeeest

Sample Output:

ei case1__this_isss_a_teest

这里不能以(j-i)%k==0来标志,因为aabbaaa,k=3,当遇到两个2的时候应该视为没有问题的键,a是没有问题的。,所以当该键位已经视为没问题时,之后出现k的倍数次时还是视为没问题的键,所以需要以不连续出现k倍数的字母进行标记。

#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 k;
char a[1010];
int book[MAX];
int issprintf[MAX];
int i=0,j=1;
int main()
{
    scanf("%d",&k);
    getchar();
    scanf("%s",a);
    memset(book,0,sizeof(book));
    memset(issprintf,0,sizeof(issprintf));
    while(i<strlen(a))
    {
        while(j<strlen(a)&&a[j]==a[i])
        {
            j++;
        }
        if((j-i)%k!=0)
        {
            book[a[i]]=1;
        }
            i=j;
    }
    for(int i=0;i<strlen(a);i++)
    {
        if(book[a[i]]==0)
        {
            cout<<a[i];
           book[a[i]]=-1;
        }
    }
    printf("\n");
    for(int i=0;i<strlen(a);)
    {
       cout<<a[i];
       if(book[a[i]]==-1)
       {
           i+=k;
       }
       else
           i++;
    }
    return 0;
}

1113 Integer Set Partition (25 分)

看懂题目就解决了

1114 Family Property (25 分)

This time, you are supposed to help us collect the data for family-owned property. Given each person’s family members, and the estate(房产)info under his/her own name, we need to know the size of each family, and the average area and number of sets of their real estate.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤1000). Then N lines follow, each gives the infomation of a person who owns estate in the format: ID Father Mother k Child​1​​ ⋯Child​k​​ M​estate​​ Area where ID is a unique 4-digit identification number for each person; Father and Mother are the ID’s of this person’s parents (if a parent has passed away, -1 will be given instead); k (0≤k≤5) is the number of children of this person; Child​i​​ 's are the ID’s of his/her children; M​estate​​ is the total number of sets of the real estate under his/her name; and Area is the total area of his/her estate.

Output Specification:

For each case, first print in a line the number of families (all the people that are related directly or indirectly are considered in the same family). Then output the family info in the format: ID M AVG​sets​​ AVG​area​​where ID is the smallest ID in the family; M is the total number of family members; AVG​sets​​ is the average number of sets of their real estate; and AVG​area​​ is the average area. The average numbers must be accurate up to 3 decimal places. The families must be given in descending order of their average areas, and in ascending order of the ID’s if there is a tie.

Sample Input:

10
6666 5551 5552 1 7777 1 100
1234 5678 9012 1 0002 2 300
8888 -1 -1 0 1 1000
2468 0001 0004 1 2222 1 500
7777 6666 -1 0 2 300
3721 -1 -1 1 2333 2 150
9012 -1 -1 3 1236 1235 1234 1 100
1235 5678 9012 0 1 50
2222 1236 2468 2 6661 6662 1 300
2333 -1 3721 3 6661 6662 6663 1 100

Sample Output:

3 8888 1 1.000 1000.000
0001 15 0.600 100.000
5551 4 0.750 100.000

把每个集合的信息用祖宗的结构体来表示。

#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=100050;
const int INF=0x3f3f3f3f;
int n,book[MAX];
int father[MAX];
struct node
{
    int id;
    int sets;
    int area;
}a[MAX];
struct Node
{
    int id,m;
    double tolsets;
    double tolarea;
}ans[MAX];
bool cmp(Node a,Node b)
{
    if(a.tolarea!=b.tolarea)
        return a.tolarea>b.tolarea;
    else
        return a.id<b.id;
}
void init()
{
    for(int i=0;i<MAX;i++)
    {
        ans[i].tolarea=0;
        ans[i].tolsets=0;
        ans[i].m=0;
    }
}
int findfather(int x)
{
    if(x==father[x])
        return x;
    else
        return father[x]=findfather(father[x]);
}
void Union(int x,int y)
{
    int t1=findfather(x);
    int t2=findfather(y);
    if(t1<t2)
    {
        father[t2]=t1;
    }
    else if(t1>t2)
    {
        father[t1]=t2;
    }
}
int main()
{
    int cnt=0;
    init();
    memset(book,0,sizeof(book));
    for(int i=0;i<MAX;i++)
        father[i]=i;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        int id,fa,ma;
        scanf("%d%d%d",&id,&fa,&ma);
        if(fa!=-1)
            Union(id,fa);
        if(ma!=-1)
            Union(id,ma);
        int k,child;
        scanf("%d",&k);
        for(int j=0;j<k;j++)
        {
            scanf("%d",&child);
            Union(id,child);
        }
        a[i].id=id;
        scanf("%d%d",&a[i].sets,&a[i].area);
    }
    for(int i=0;i<n;i++)
    {
        int f=findfather(a[i].id);
        ans[f].id=f;
        ans[f].tolsets+=a[i].sets;
        ans[f].tolarea+=a[i].area;
        book[f]=1;
    }
    for(int i=0;i<MAX;i++)
    {
        int f=findfather(i);
        ans[f].m++;
    }
    for(int i=0;i<MAX;i++)
    {
        cnt+=book[i];
        ans[i].tolsets=ans[i].tolsets/ans[i].m;
        ans[i].tolarea=ans[i].tolarea/ans[i].m;
    }
    sort(ans,ans+MAX,cmp);
    printf("%d\n",cnt);
    for(int i=0;i<cnt;i++)
    {
        printf("%04d %d %.3f %.3f\n",ans[i].id,ans[i].m,ans[i].tolsets,ans[i].tolarea);
    }
    return 0;
}

1115 Counting Nodes in a BST (30 分)

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 or equal to the node’s key.
The right subtree of a node contains only nodes with keys greater than the node’s key.
Both the left and right subtrees must also be binary search trees.
Insert a sequence of numbers into an initially empty binary search tree. Then you are supposed to count the total number of nodes in the lowest 2 levels of the resulting tree.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤1000) which is the size of the input sequence. Then given in the next line are the N integers in [−10001000] which are supposed to be inserted into an initially empty binary search tree.

Output Specification:

For each case, print in one line the numbers of nodes in the lowest 2 levels of the resulting tree in the format:
n1 + n2 = n
where n1 is the number of nodes in the lowest level, n2 is that of the level above, and n is the sum.

Sample Input:

9
25 30 42 16 20 20 35 -5 28

Sample Output:

2 + 4 = 6

比较简单,练了练两个搜索,复习了一遍BST的建立过程。

//bfs
#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=100050;
const int INF=0x3f3f3f3f;
int level[MAX];
int t=1,maxlevel=0;
struct node
{
    int data;
    int layer;
    node* lchild;
    node* rchild;
};
node* newnode(int x)
{
    node* Node=new node;
    Node->data=x;
    Node->lchild=Node->rchild=NULL;
    return Node;
}
void Insert(node* &root,int x)
{
    if(root==NULL)
    {
       root=newnode(x);
       return ;
    }
    if(x<=root->data)
    {
        Insert(root->lchild,x);
    }
    else if(x>root->data)
    {
        Insert(root->rchild,x);
    }
}
void bfs(node* root)
{
    queue<node*>q;
    root->layer=1;
    q.push(root);
    while(!q.empty())
    {
        node* top=q.front();
        q.pop();
        level[top->layer]++;
        maxlevel=max(maxlevel,top->layer);
        if(top->lchild!=NULL)
        {
            top->lchild->layer=top->layer+1;
            q.push(top->lchild);
        }
        if(top->rchild!=NULL)
        {
            top->rchild->layer=top->layer+1;
            q.push(top->rchild);
        }
    }
}
int main()
{
    int n,x;
    scanf("%d",&n);
    node* root=NULL;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&x);
        Insert(root,x);
    }
    bfs(root);
    printf("%d + %d = %d",level[maxlevel],level[maxlevel-1],level[maxlevel]+level[maxlevel-1]);
    return 0;
}

//dfs
#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=100050;
const int INF=0x3f3f3f3f;
int level[MAX]={0};//层数对应的node数量
int t=1,maxlevel=0;
struct node
{
    int data;
    node* lchild;
    node* rchild;
};
node* newnode(int x)
{
    node* Node=new node;
    Node->data=x;
    Node->lchild=Node->rchild=NULL;
    return Node;
}
void Insert(node* &root,int x)
{
    if(root==NULL)
    {
       root=newnode(x);
       return ;
    }
    if(x<=root->data)
    {
        Insert(root->lchild,x);
    }
    else if(x>root->data)
    {
        Insert(root->rchild,x);
    }
}
void dfs(node* root,int depth)
{
    if(root==NULL)
    {
        return;
    }
    if(depth>maxlevel)
    {
        maxlevel=depth;
    }
    level[depth]++;
    if(root->lchild!=NULL)
        dfs(root->lchild,depth+1);
    if(root->rchild!=NULL)
        dfs(root->rchild,depth+1);
}
int main()
{
    int n,x;
    scanf("%d",&n);
    node* root=NULL;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&x);
        Insert(root,x);
    }
    dfs(root,1);
    printf("%d + %d = %d",level[maxlevel],level[maxlevel-1],level[maxlevel]+level[maxlevel-1]);
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值