pat甲级真题分类-逻辑处理

1

7-3 File Path (25 分)

#include <iostream>
#include <cstring>
#include <unordered_map>
using namespace std;
const int N=1010;
int last[N]= {
   0},pre[10010]= {
   0};   //pre[i[存放的是i的父亲,last存放的是同一层中最后一个值,比如1234与2234在同一层,则last[1]存放的是2234,注意last的下标是按照给出的字符串之前的空格决定的

//注意last的下标表示字符串之前的空格,范围用N来表示,但是pre的下标存放的是4位数字,所以范围最少1w

unordered_map<int,int> mp;


void dfs(int x)
{
   
	if(x==0)
    {
   
		printf("0000");
		return;
	}
	dfs(pre[x]);
	printf("->%04d",x);
}

int main()
{
   
	int n,k,id;

	cin>>n;             //读入n

	getchar();          //吸收一个空格

	string input;

	for(int i=0; i<n; i++)
    {
   
		getline(cin,input);
		int cnt=0;

		while(*input.begin()==' ')
		{
   
			input.erase(input.begin());
			cnt++;//计算前面有几个空格
		}

		int key=stoi(input);            //将输入的数字改为字符串
		mp[key]=1;          //这个是为了防止给出的数字不在输入的目录中出现



		pre[key]=last[cnt-1];//将上一层的最后结点设置为当前结点的父节点
		last[cnt]=key;//更新当前层的最后一个结点
	}



	cin>>k;
	int val;
	while(k--)
    {
   
		scanf("%d",&val);
		if(mp.count(val)==0)        //如果要查询的数字在mp中不存在,则输出not found
            printf("Error: %04d is not found.",val);
		else
            dfs(val);        //否则深搜
		cout << endl;
	}
	return 0;
}

2

7-1 Panda and PP Milk (20 分)


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

/*
    这道题的核心思路在于寻找低谷,比如样例中的100和138,然后数据向两边扩散
    1.从左往右开始遍历,初始值设置为200,如果右边的值比左边大则加100;如果右边的值等于左边的值则牛奶量不变;如果右边的值比左边的值小则修改为200,这样一定是能找到低谷
    你想,第一个数设置为200,后面如果体重比它大则往上升,如果相同则区域平静,如果小则还是200,所以一定能找到低谷
    2.同样从右向左按上述方法再次遍历,同样也能找到低谷
    3.这样取同一位置中,两个vector较大的值,因为处于低谷附近所能找到的就是最终的结果

*/

const int maxn=10003;

struct node
{
   
    int milk;
    int weight;
}Node[maxn];

vector<int> LR,RL;

int n;

int main()
{
   
    cin >> n;
    for(int i=0; i<n; i++)
    {
   
        cin >> Node[i].weight;
    }
    Node[0].milk=200;
    LR.push_back(Node[0].milk);

    for(int i=1; i<n; i++)
    {
   
        if(Node[i].weight>Node[i-1].weight)
        {
   
            Node[i].milk=Node[i-1].milk+100;
        }
        else if(Node[i].weight==Node[i-1].weight)
        {
   
            Node[i].milk=Node[i-1].milk;
        }
        else
        {
   
            Node[i].milk=200;
        }
        LR.push_back(Node[i].milk);
    }

    Node[n-1].milk=200;
    RL.push_back(Node[n-1].milk);

    for(int i=n-2; i>=0; i--)
    {
   
        if(Node[i].weight>Node[i+1].weight)
        {
   
            Node[i].milk=Node[i+1].milk+100;
        }
        else if(Node[i].weight==Node[i+1].weight)
        {
   
            Node[i].milk==Node[i+1].milk;
        }
        else
        {
   
            Node[i].milk=200;
        }
        RL.push_back(Node[i].milk);
    }

    reverse(RL.begin(),RL.end());

    int sum=0,temp;
    for(int i=0; i<n; i++)
    {
   
        temp=max(LR[i],RL[i]);
        sum+=temp;
    }
    cout << sum;
}


3

7-2 The Judger (25 分)


#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);

    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;
}


4

7-3 Safari Park (25 分)

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

const int maxn=511;

int n,r,k;

vector<int> G[maxn];

int main()
{
   
    cin >> n >> r >> k;
    for(int i=0; i<r; i++)
    {
   
        int a,b;
        cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    int m;
    cin >> m;
    for(int i=0; i<m; i++)
    {
   
        int v[maxn];
        unordered_set<int> s;
        for(int j=1; j<=n;<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值