11/23 PAT(甲级)2019年秋季

单词组:
  1. digit 位数
  2. the greatest common divisor 最大公约数
  3. prime 素数
  4. the ascending order of 升序
  5. nonnegative integer 非负整数
  6. positive integer 正整数
  7. binary 二进制
  8. postfix 后缀
题型.1.找规律 2.链表 3.树的遍历4.最短路

7-1 Forever

得分: 16 / 20

"Forever number" is a positive integer A with K digits, satisfying the following constrains:
the sum of all the digits of A is m;
the sum of all the digits of A+1 is n; and
the greatest common divisor of m and n is a prime number which is greater than 2.
Now you are supposed to find these forever numbers.

Input Specification:

Each input file contains one test case. For each test case, the first line contains a positive integer N (≤5). Then N lines follow, each gives a pair of K (3<K<10) and m (1<m<90), of which the meanings are given in the problem description.

Output Specification:

For each pair of K and m, first print in a line Case X, where X is the case index (starts from 1). Then print n and A in the following line. The numbers must be separated by a space. If the solution is not unique, output in the ascending order of n. If still not unique, output in the ascending order of A. If there is no solution, output No Solution.

Sample Input:

2
6 45
7 80

Sample Output:

Case 1
10 189999
10 279999
10 369999
10 459999
10 549999
10 639999
10 729999
10 819999
10 909999
Case 2
No Solution

直接暴搜超时,但也能拿大部分的分数,所以基本分争取全拿。
网上搜了比较好的思路。
1.若m的个位不为9,加1后最大公约数必为1<2,所以不成立,个位必定是9.
2.若m十位不是9,n=m-8
若m的百位不是9,n=m-17
n=m-t*9+1;(t为末尾连续9的个数)
定了末尾9的个数再往后枚举

#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,m,k;
int sumnum(int x)
{
    int sum=0;
    while(x)
    {
        sum+=x%10;
        x/=10;
    }
    return sum;
}
int gcd(int a,int b)
{
    if(b==0)
    return a;
    else
    return gcd(b,a%b);
}
bool prime(int x)
{
    if(x<=2)
        return false;
    for(int i=2;i<=(int)sqrt(1.0*x);i++)
    {
        if(x%i==0)
            return false;
    }
    return true;
}
int main()
{
    int N,addition;
   scanf("%d",&n);
   for(int j=1;j<=n;j++)
   {
   int flag=0;
   scanf("%d%d",&k,&m);
   printf("Case %d\n",j);
   int MIN=(int)pow(10.0,k-1);
   int MAX=(int)pow(10.0,k)-1;
   for(int t=1;t<6;t++)
   {
      N=m-t*9+1;
      if(prime(gcd(N,m))==false)
        continue;
    MIN+=pow(10.0,t)-1;
    addition=pow(10.0,t);
   for(int i=MIN;i<MAX;i+=addition)
   {
       if(sumnum(i)==m)
       {
           flag=0;
           printf("%d %d\n",n,i);
       }
   }
   if(flag==0)
    printf("No Solution\n");
   }
   }
   return 0;
}

7-2 Merging Linked Lists

得分: 25 / 25

Sample Input:

00100 01000 7
02233 2 34891
00100 6 00001
34891 3 10086
01000 1 02233
00033 5 -1
10086 4 00033
00001 7 -1

Sample Output:

01000 1 02233
02233 2 00001
00001 7 34891
34891 3 10086
10086 4 00100
00100 6 00033
00033 5 -1

常规题,给出两个链表,短的那个需要反转,而且题目也保证了长的链表一定是短的链表两倍长度,将短链表插入长链表,​a1→a2→bm→a3 →a4 →bm−1,放在vector里面操作就好了。

#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=100500;
const int INF=0x3f3f3f3f;
struct Node
{
  int address;
  int data;
  int next;
}node[MAX];
vector<Node>list1,list2;
int main()
{
    int start1,start2,n;
    scanf("%d%d%d",&start1,&start2,&n);
    int ads;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&ads);
        scanf("%d%d",&node[ads].data,&node[ads].next);
        node[ads].address=ads;
    }
    int p=start1;
    while(p!=-1)
    {
        list1.push_back(node[p]);
        p=node[p].next;
    }
    p=start2;
     while(p!=-1)
    {
        list2.push_back(node[p]);
        p=node[p].next;
    }
    if(list1.size()>list2.size())
    {
        vector<Node>temp;
        temp=list1;
        list1=list2;
        list2=temp;
    }
    vector<Node>res;
    int t=0;
    for(int i=0;i<list2.size();i++)
    {
        res.push_back(list2[i]);
        if(i==t*2+1)
        {
            if(t<list1.size())
            {
            res.push_back(list1[list1.size()-t-1]);
            t++;
            }
        }
    }
    for(int i=0;i<res.size();i++)
    {
        res[i].next=res[i+1].address;
    }
    for(int i=0;i<res.size()-1;i++)
    {
        printf("%05d %d %05d\n",res[i].address,res[i].data,res[i].next);
    }
    printf("%05d %d -1",res[res.size()-1].address,res[res.size()-1].data);
   return 0;
}

7-3 Postfix Expression

未作答 得分: 0 / 25
​​

Given a syntax tree (binary), you are supposed to output the corresponding postfix expression, with parentheses reflecting the precedences of the operators.

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 syntax tree. Then N lines follow, each gives the information of a node (the i-th line corresponds to the i-th node) in the format:

data left_child right_child

where data is a string of no more than 10 characters, left_child and right_child are the indices of this node’s left and right children, respectively. The nodes are indexed from 1 to N. The NULL link is represented by −1. The figures 1 and 2 correspond to the samples 1 and 2, respectively.
AltAlt

Output Specification:

For each case, print in a line the postfix expression, with parentheses reflecting the precedences of the operators.There must be no space between any symbols.

Sample Input 1:

8
* 8 7
a -1 -1
* 4 1
+ 2 5
b -1 -1
d -1 -1
- -1 6
c -1 -1

Sample Output 1:

(((a)(b)+)(©(-(d))))

Sample Input 2:

8
2.35 -1 -1
* 6 1
- -1 4
% 7 8
+ 2 3
a -1 -1
str -1 -1
871 -1 -1

Sample Output 2:

(((a)(2.35)*)(-((str)(871)%))+)

很久没做树的题目看到数据没啥感觉,知道是后序遍历题看了半天没看懂数据啥意思/(ㄒoㄒ)/~~,其实就是每个点对应的下标罢了,然后后序遍历的时候和样例的对照一下,当左子树为空,右子树非空的时候,先输出根节点的值再去递归右子树,这题蛮简单的,属实不应该0分!!!憨憨了

#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=10050;
const int INF=0x3f3f3f3f;
struct node
{
  char data[10];
  int lchild;
  int rchild;
}Node[MAX];
int book[MAX];
void postorder(int x)
{
    if(x==-1)
        return ;
    if(Node[x].lchild==-1&&Node[x].rchild!=-1)
    {
        printf("(");
        printf("%s",Node[x].data);
        postorder(Node[x].rchild);
        printf(")");
    }
    else
    {
    printf("(");
    postorder(Node[x].lchild);
    postorder(Node[x].rchild);
    printf("%s",Node[x].data);
    printf(")");
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    memset(book,0,sizeof(book));
    for(int i=1;i<=n;i++)
    {
        scanf("%s",Node[i].data);
        scanf("%d%d",&Node[i].lchild,&Node[i].rchild);
        book[Node[i].lchild]=1;
        book[Node[i].rchild]=1;
    }
    int i;
    for(i=1;i<=n;i++)
    {
        if(book[i]==0)
            break;
    }
    postorder(i);
   return 0;
}

7-4 Dijkstra Sequence

得分: 30 / 30

Sample Input:

5 7
1 2 2
1 5 1
2 3 1
2 4 1
2 5 2
3 5 1
3 4 1
4
5 1 3 4 2
5 3 1 2 4
2 3 4 5 1
3 2 1 5 4

Sample Output:

Yes
Yes
Yes
No

给出点数,边数,每条边的起点,终点,边权。
给出一些路径判断是否是dijkstra中的路径。
每次按照给的路径去进行dijkstra,取最短的那条边时,将所有可以的点放到set里面,判断a[i]是否存在。

#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=10050;
const int INF=0x3f3f3f3f;
int book[MAX];
int dis[MAX];
int a[MAX];
int n,m;
struct node
{
    int v,w;
};
vector<node>edge[MAX];
bool dijkstra()
{
     memset(book,0,sizeof(book));
     fill(dis,dis+MAX,INF);
     dis[a[0]]=0;
     for(int i=0;i<n;i++)
     {
         int u=-1,MIN=INF;
         set<int>st;
         for(int j=1;j<=n;j++)
         {
             if(book[j]==0&&dis[j]<MIN)
             {
                 MIN=dis[j];
                 st.clear();
                 st.insert(j);
             }
             else if(book[j]==0&&dis[j]==MIN)
             {
                 st.insert(j);
             }
         }
         u=a[i];
         if(st.count(a[i])==0)
         {
             return false;
         }
         book[u]=1;
         for(int j=0;j<edge[u].size();j++)
         {
             int k=edge[u][j].v;
             if(book[k]==0&&dis[k]>dis[u]+edge[u][j].w)
             {
                 dis[k]=dis[u]+edge[u][j].w;
             }
         }
     }
     return true;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        int x,y,z;
        node temp;
        scanf("%d%d%d",&x,&y,&z);
        temp.v=y;
        temp.w=z;
        edge[x].push_back(temp);
        temp.v=x;
        edge[y].push_back(temp);
    }
    int num;
    scanf("%d",&num);
    for(int i=0;i<num;i++)
    {
        for(int j=0;j<n;j++)
        {
        scanf("%d",&a[j]);
        }
        if(dijkstra()==true)
        {
              printf("Yes\n");
        }
        else
        {
              printf("No\n");
        }
    }
   return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值