PAT (Level A) 2020 Spring Exam

7-1

#include<iostream>
#include<cstring>
using namespace std;

    /*
        s.substr(pos, n) 从s的pos位置开始,截取n个字符
        s.substr(pos)   从s的pos位置开始直接截取到末尾
        stoi将字符串转化为数字
    */
string s;

bool isPrime(int x)
{
    
    
    if(x==1)
        return false;
    for(int i=2; i*i<x; i++)
    {
    
    
        if(x%i==0)
            return false;
    }
    return true;
}

int main()
{
    
    
    cin >> s;
    bool flag=true;
    string temp;
    int temp1;
    for(int i=0; i<s.size(); i++)
    {
    
    
        temp=s.substr(i);
        int temp1=stoi(temp);
        cout << temp << " ";
        if(isPrime(temp1))
        {
    
    
            cout << "Yes" << endl;
        }
        else
        {
    
    
            flag=false;
            cout << "No" << endl;
        }
    }
    if(flag==true)
        cout << "All Prime!";
    return 0;
}

7-2

#include<iostream>
#include<cmath>
#include<unordered_set>
using namespace std;

/*
在样本输入1中:9是和之前的重复了,37是找不到与之前的差,40是有41-1得来,对于第5轮,1号玩家是7,2号玩家也是7,但不淘汰2是因为1号玩家在第3轮的
时候已径被淘汰,所以他输入的7就没有用

整个题目就只有两个限制条件:
1.如果该数是之前存在的不行
2.如果该数不是之前任意的两个数只差,不行

*/


unordered_set<int> s,oid;   //设置unordered_set数组,不会自动排序,基于哈希表,数据数据插入和查找的时间复杂度很低
//oid是存放已经被淘汰的人的编号


int a[15][1005];

bool jugde(int x)   //在已存在的列表中,看是否能找到x为某两个数的差
{
    
    
    unordered_set<int>::iterator it=s.begin();   //在输入的s数组中,寻找x是否存在
    for(;it!=s.end();it++)
    {
    
    
        if(s.find((*it)+x)!=s.end())   //x表示当前要查找的数,it表示遍历s的数,然后在s中查找看是否存在,如果存在则返回true,否则遍历一圈没有直接返回false
            return true;   //找的到,则直接返回true
    }
    return false;  
}

int main()
{
    
    
    int q,p,n,m;
    cin >> q >> p >> n >> m;    //分别表示第1个值,第2个值,n个玩家,m个循环
    s.insert(q);
    s.insert(p);
    bool f=true;
    for(int i=0;i<n;i++)    //4个人
    {
    
    
        for(int j=0;j<m;j++)   //5个轮回
        {
    
    
            scanf("%d",&a[i][j]);  //输入数据
        }
    }
    for(int j=0;j<m;j++)    //按照轮回作为第1层for循环
    {
    
    
        for(int i=0;i<n;i++)        //按照人数作为第2层for循环
        {
    
    
            if(oid.find(i)!=oid.end())  //如果在概论中,第i号玩家已经被淘汰则直接跳过下面的内容
                continue;
            int x=a[i][j];           //将当前第j轮的第i个玩家的值输出
            if(s.find(x)!=s.end() || !jugde(x))   //如果在s中能知道x,说明之前已径有x了,或者如果在s中没有知道合适的值,则需要将第i号玩家放入到oi中
            {
    
    
                oid.insert(i);        //oid表示淘汰的人
                printf("Round #%d: %d is out.\n",j+1,i+1);  //这表示被淘汰的人,则表示该玩家在该伦中被淘汰
            //对于题中说,在一轮中,如果有多个玩家被淘汰,则按照编号的升序进行排列,我们每次放入值的时候就是按照玩家的升序进行寻找
            }
            else
            {
    
    
                s.insert(x);  //将x插入到s中,如果满足要求就把x放入到总库中
            }

        }
    }
    //下来就该输出,胜利的人的编号,或者no winners
    bool flag=false;         //设置flag为false
    for(int i=0;i<n;i++)        //遍历循环n个人
    {
    
    
        if(oid.find(i)==oid.end())      //如果在剔除人的数组中,找不到i
        {
    
    
            if(!flag)          //flag为false执行,flag为true不执行,则执行下面的语句
            {
    
    
                flag=true;   //标记flag为true
                printf("Winner(s): %d",i+1);  //输出胜利者
            }
            else  
                printf(" %d",i+1);
        }
    }
    if(!flag)   //如果flag经过上面的遍历,还是false,表示所有的人都已经剔除,则直接输出no winner
        printf("No winner.");

    return 0;
}

7-3

#include<iostream>
#include<vector>
using namespace std;

const int maxn=555;

struct node
{
    
    
    int bianhao;
    vector<int> child;
}Node[maxn];

int n,r,k;

int inq[maxn]={
    
    0};

int main()
{
    
    
    cin >> n >> r >> k;
    int temp1,temp2;
    for(int i=1; i<=r; i++)
    {
    
    
        cin >> temp1 >> temp2;
        Node[temp1].child.push_back(temp2);
    }
    int kk;
    cin >> kk;
    int temp3;
    for(int i=0; i<kk; i++)
    {
    
    
        fill(inq,inq+maxn,0);
        for(int j=1; j<=n; j++)
        {
    
    
            cin >> temp3;
            Node[j].bianhao=temp3;
            inq[temp3]++;
        }
        int ans=0;
        for(int kk=1; kk<=maxn; kk++)
            if(inq[kk]!=0)
                ans++;
        if(ans>k)
        {
    
    
            cout << "Error: Too many species." << endl;
        }
        else if(ans<k)
        {
    
    
            cout << "Error: Too few species." << endl;
        }
        else
        {
    
    
            bool flag=true;
            for(int ss=1; ss<=n; ss++)
            {
    
    
                for(int ww=0; ww<Node[ss].child.size(); ww++)
                {
    
    
                    if(Node[ss].bianhao==Node[Node[ss].child[ww]].bianhao)
                    {
    
    
                        flag=false;
                        break;
                    }
                }
                if(flag==false)
                    break;
            }
            if(flag==true)
                cout << "Yes" << endl;
            else
                cout << "No" << endl;
        }
    }
    return 0;
}

7-4

#include<bits/stdc++.h>
using namespace std;

/*
    如果之前对转换选择排序一无所知的话,单纯根据题中的例子,我认为无法知道具体的代码思路,这道题就类似
    与之前那道是堆排序还是插入排序的思路,也是先解释什么是堆排序什么是插入排序,但是如果之前无法知道相管
    的排序方法,那必然做不了,所以我的策略还是对已经做过的题要精通熟悉,同时不断的耍新题

*/
int main()
{
    
    
	int n,m,index = 0,ind = 0,num[100010];
	cin>>n>>m;
	multiset<int> ans[1000],m1,m2;//m1为first runs,m2为second runs    c++语言中,multiset是<set>库中一个非常有用的类型,它可以看成一个序列,插入一个数,删除一个数都能够在O(logn)的时间内完成,而且他能时刻保证序列中的数是有序的,而且序列中可以存在重复的数。
	//multiset具有自动排序的功能,这个m1,m2就是控制所分配的块数
	for(int i=0;i<n;i++)
    {
    
    
		cin>>num[i];    //在num中先输入n个数字
		if(i<m)   //先再m1中插入,并且在ans0中插入
		{
    
    
			m1.insert(num[i]);  //在m1中输入插入数字
			ans[0].insert(num[i]);//同时将num[i]插入ans[0]
		}
	}

	for(int i=m;i<n;i++)   //从m这个位置开始访问数字num[i]
	{
    
    
		if(num[i] > *m1.begin())  //*m1.begin是最小的数
		{
    
    
			ans[index].insert(num[i]);   //装入runs[index]
			m1.erase(m1.begin());   //m1消除头一个值
			m1.insert(num[i]);  //在插入num[i]
		}
		else  //其实,这个现在想来就是,当前这个数字num[i]是不同于前一个块中的,所以要把他放入到第2个块中
		{
    
    
			m2.insert(num[i]);  //在m2中插入num[i]
			m1.erase(m1.begin());  //前面那个if已经将m1中的值,进行比较过了,所以要消除m1中的头一个值
			ans[index+1].insert(num[i]); //将当前的num[i]插入到第index+1个块中,注意这里不是index++,只是表示下一个index
		}
        if(m1.size()==0)  //如果m1为空了,则index++,将m2中的所有值给m1,清空m2,说白了其实就是以m1,m2来撼动整个地球
        {
    
    		//m1中没有可替换的(m2满了),换
			index++;    //目前runs下标
			m1 = m2;
			m2.clear();
		}
	}

    while(ans[ind].size()!=0)    //寻找他分了几块
        ind++;

	for(int i=0;i<ind;i++)   //按照块数进行输出数字
	{
    
    	 //打印
		int st=0;
		for(int nn:ans[i])  //这个是访问multiset二维数组的值,i从0开始一直到ind,然后for循环,从ans[i]为第1个,
		{
    
    
			if(st!=0)  //这个只是为了控制输出
                cout<<" ";
			cout << nn;  //直接输出就好
			st++;
		}

		cout<<endl; //换行
	}
	return 0;
}


Guess you like

Origin blog.csdn.net/wsfhdhjs/article/details/109676305