首页 > 试题广场 >

人口普查(20)

[编程题]人口普查(20)
  • 热度指数:21476 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。



这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过200岁的老人,而今天是2014年9月6日,所以超过200

岁的生日和未出生的生日都是不合理的,应该被过滤掉。

输入描述:
输入在第一行给出正整数N,取值在(0, 105];随后N行,每行给出1个人的姓名(由不超过5个英文字母组成的字符串)、以及
按“yyyy/mm/dd”(即年/月/日)格式给出的生日。题目保证最年长和最年轻的人没有并列。


输出描述:
在一行中顺序输出有效生日的个数、最年长人和最年轻人的姓名,其间以空格分隔。
示例1

输入

5<br/>John 2001/05/12<br/>Tom 1814/09/06<br/>Ann 2121/01/30<br/>James 1814/09/05<br/>Steve 1967/11/20

输出

3 Tom John
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * 人口普查
 * 题目描述
 * 某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。
 * 这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过200岁的老人,
 * 而今天是2014年9月6日,所以超过200岁的生日和未出生的生日都是不合理的,应该被过滤掉。
 * 输入描述:
 * 输入在第一行给出正整数N,取值在(0, 105];随后N行,每行给出1个人的姓名(由不超过5个
 * 英文字母组成的字符串)、以及按“yyyy/mm/dd”(即年/月/日)格式给出的生日。题目保证最
 * 年长和最年轻的人没有并列。
 * 输出描述:
 * 在一行中顺序输出有效生日的个数、最年长人和最年轻人的姓名,其间以空格分隔。
 * 输入例子:
 * 5
 * John 2001/05/12
 * Tom 1814/09/06
 * Ann 2121/01/30
 * James 1814/09/05
 * Steve 1967/11/20
 * 输出例子:
 * 3 Tom John
 *
 * @author shijiacheng
 * @date 2018/2/1
 */
public class B1018Census {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        List<Person> list = new ArrayList<>();
        for (int i = 0; i < N; i++) {
            Person p = new Person();
            p.name = sc.next();
            p.setDateStr(sc.next());
            list.add(p);
        }

        int count = 0;
        int min = 0;
        int max = Integer.MAX_VALUE;
        String maxName = "";
        String minName = "";
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).date >= 18140906 && list.get(i).date <= 20140906) {
                count++;
                if (list.get(i).date < max) {
                    max = list.get(i).date;
                    maxName = list.get(i).name;
                }

                if (list.get(i).date > min) {
                    min = list.get(i).date;
                    minName = list.get(i).name;
                }
            }

        }
        System.out.println(count + " " + maxName + " " + minName);
    }

    static class Person {
        String name;
        int date;
        String dateStr;

        public void setDateStr(String dateStr) {
            this.dateStr = dateStr;
            String[] str = dateStr.split("/");
            this.date = Integer.parseInt(str[0]) * 10000
                    + Integer.parseInt(str[1]) * 100 + Integer.parseInt(str[2]);
        }
    }
}
发表于 2018-02-01 22:16:02 回复(0)
#include <iostream>
#include <algorithm>
using namespace std;
struct Person
{
    string name;
    string birthday;
};
bool compare(const Person& s1, const Person& s2)
{
    if (s1.birthday < s2.birthday)
        return true;
    else
        return false;
}
int main()
{
    int N;
    vector<Person> man;
    Person temp;
    string compare1 = "2014/09/06";
    string compare2 = "1814/09/06";
    cin >> N;
    for ( int i = 0; i < N; ++i)
    {
        cin >> temp.name >> temp.birthday;
        if (temp.birthday < compare1 && temp.birthday >= compare2)
            man.push_back(temp);
    }
    sort(man.begin(), man.end(), compare);
    cout <<man.size()<<" " <<man.front().name<<" "<<man.back().name;
    return 0;
}
编辑于 2015-06-16 16:25:06 回复(2)
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class Main {

	public static class Person implements Comparable<Person> {
	
		String name;
		String birthday;

		public Person(String name, String birthday) {
			this.name = name;
			this.birthday = birthday;
		}

		public int compareTo(Person o){ 
			return  this.birthday.compareTo(o.birthday);
		}
	}

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		ArrayList<Person> person = new ArrayList<>();
		for (int i = 0; i < n; i++) {
			Person p = new Person(in.next(), in.next());
			person.add(p);
		}
		Collections.sort(person);
		Person p1 = new Person("tom","2014/09/06");
		Person p2 = new Person("tom","1814/09/06");
		int count = 0;
		boolean flag1 = true;
		String[] name = new String[2];
		for (Person p : person) {
			if (p.compareTo(p2) >= 0 && p.compareTo(p1) <= 0) {
				count++;
			}
			if (p.compareTo(p2) >= 0 && flag1) {
				name[0] = p.name;
				flag1 = false;
			}
			if (p.compareTo(p1) <= 0) {
				name[1] = p.name;
			}
		}
		System.out.printf("%d %s %s", count, name[0], name[1]);
	}
}
发表于 2017-01-20 13:10:26 回复(0)
TNND,测试用例居然还有这么多同一天生日的坑我
void test03()
{
	/*
		"1814/09/06" ~ "2014/09/06" 的才正确
	*/
	
	int nums, flag = 1, count = 0;
	map<string, string> person;
	string name, birth, youngest, oldest;
	
	cin >> nums;
	while(nums--){
		cin >> name >> birth;
		if(birth>="1814/09/06" && birth<="2014/09/06") count++;
		person.insert(make_pair(birth, name));
	}
	map<string, string>::iterator map_it = person.begin();
	
	while(map_it!=person.end()){
		if( map_it->first<"1814/09/06" || map_it->first>"2014/09/06" ){
			map_it++;
			continue;
		}
		
		if(flag){
			oldest = map_it->second;
			flag = 0;
		}
		youngest = map_it->second;
		map_it++;
	}
	
	cout << count << " " << oldest << " " << youngest;

} 

int main()
{
	test03();
    
    return 0;
}


发表于 2020-02-11 21:11:01 回复(0)
注意本题有一个陷阱,信息会出现重复的,但答案默认这些不是相同的。所以不建议构造字典。
发表于 2018-03-04 11:35:11 回复(0)
#include<stdio.h>
#include<string.h>
int main (){//the shorter,the better.
    int n,i,cnt;char b[11],max[11]="1814/09/06",min[11]="2014/09/06",t[6],o[6],y[6]; 
    for(;~scanf("%d",&n);printf("%d %s %s\n",cnt,y,o))
       for (cnt=i=0; i < n&&~scanf("%s %s",t,b);strcmp(b,"1814/09/06")<0||strcmp(b,"2014/09/06")>0?:(strcmp(max,b)>0?:(strcpy(max,b),strcpy(o,t),1),strcmp(min,b)<0?:(strcpy(min,b),strcpy(y,t),1),++cnt),i++);
}
//ps:ANSI C has lots of handsome functions,why not just use then?-_-
编辑于 2018-01-30 21:04:26 回复(0)
一切为了输出
  1. #include <iostream>
  2. using  namespace std;
  3. intmain() {
  4.     string s,bname,sname;intyear,moon,day,n,k=0;chart;cin>>n;
  5.     for(inti=0,by=0,sy=750000;i<n;i++) {
  6.         cin >> s >> year >> t >> moon >> t >> day;
  7.         if(year*365+moon*30+day>=662386&&year*365+moon*30+day<=735386){k++;
  8.             if(by<year*365+moon*30+day){by=year*365+moon*30+day;bname=s;}
  9.             if(sy>year*365+moon*30+day){sy=year*365+moon*30+day;sname=s;}}}
  10.     cout<<k<<" "<<sname<<" "<<bname;
  11. }

发表于 2018-03-07 11:04:15 回复(1)
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 100010;
struct Per{
	char name[5];
	int year, month, day;
	int rank;
}per[maxn];
bool judge(Per a){
	if (a.year>2014 || a.year<1814)
		return false;
	else if (a.year == 2014 && a.month>9 || a.year == 1814 && a.month<9)
		return false;
	else if (a.year == 2014 && a.month == 9 && a.day>6 || a.year == 1814 && a.month == 9 && a.day<6)
		return false;
	else return true;
}
bool cmp(Per a, Per b){
	if (a.rank != b.rank)return a.rank > b.rank;
	if (a.year != b.year)
		return a.year>b.year;
	else if (a.month != b.month)
		return a.month>b.month;
	else return a.day>b.day;
}
int main(){
	int n;
	cin >> n;
	int cnt = 0;
	for (int i = 0; i<n; i++){
		cin >> per[i].name;
		scanf_s("%d/%d/%d", &per[i].year, &per[i].month, &per[i].day);
		if (judge(per[i])){
			cnt++;
			per[i].rank = 1;
		}
		else
			per[i].rank = 0;
	}
	cout << cnt << " ";
	sort(per, per + n, cmp);
	cout << per[cnt - 1].name<<" " << per[0].name;
}

发表于 2021-05-07 17:37:25 回复(0)

思路

  1. 年月日比较法,按顺序依次比较年月日,封装成函数。

  2. 利用字符串的顺序比较,借助STLstring直接比较得出结果,不需要封装函数。

方法一

注意:结果为0时,只需要输出0,而不需要其他,包括空格

年月日依次比较

/*
 * app=PAT-Basic lang=c++
 * https://pintia.cn/problem-sets/994805260223102976/problems/994805293282607104
 */
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 100010;
struct person{
    char name[6];
    int year;
    int month;
    int day;
}temP,maxP,minP,max,min;
/* 
 * 年份,月份,天均小于等于 --- 年龄大于等于
 */
bool lessEqu(person p1,person p2){
    if (p1.year != p2.year)
        return p1.year <= p2.year;
    if (p1.month != p2.month)
        return p1.month <= p2.month;
    else
        return p1.day <= p2.day;
}
/* 
 * 年份,月份,天均大于等于 --- 年龄小于等于
 */
bool moreEqu(person p1, person p2){
    if (p1.year != p2.year)
        return p1.year >= p2.year;
    if (p1.month != p2.month)
        return p1.month >= p2.month;
    else
        return p1.day >= p2.day;
}
void init(){
    minP.year = min.year = 1814;
    maxP.year = max.year = 2014;
    maxP.month = minP.month = max.month = min.month = 9;
    maxP.day = minP.day = max.day = min.day = 6;
}
int main()
{
    int n;
    int year, month, day;
    init();
    scanf("%d",&n);
    int count = 0;
    for (int i = 0; i < n; i++){
        scanf("%s %d/%d/%d", temP.name, &temP.year, &temP.month, &temP.day);
        if (lessEqu(temP, max) && moreEqu(temP, min)){
            count++;
            if (lessEqu(temP, maxP)){
                maxP = temP;
            }
            if (moreEqu(temP, minP)){
                minP = temP;
            }
        }
    }
    printf("%d",count);
    if (count!=0)
        printf(" %s %s", maxP.name, minP.name);
    return 0;
}

方法二

直接利用STL:string比较。不需要自封装比较函数,但是不熟悉string方法的,需要知道string的比较判断,是按照字符顺序的ascii码比较,所以可以用string的直接比较来解决。

/*
 * app=PAT-Basic lang=c++
 * https://pintia.cn/problem-sets/994805260223102976/problems/994805293282607104
 */
#include <cstdio>
#include <string>
#include <iostream>
using namespace std;
int main(){
    int n;
    scanf("%d",&n);
    int count = 0;
    string s1, s2, left = "1814/09/06", right = "2014/09/06";
    string max = right, min = left, maxName, minName;
    for (int i = 0; i < n; i++){
        cin >> s1 >> s2;
        if (s2 >= left && s2 <= right){
            count++;
            if (s2 < max){
                max = s2;
                maxName = s1;
            }
            if (s2 >min){
                min = s2;
                minName = s1;
            }
        }
    }
    cout << count;
    if (count != 0)
        cout << " " << maxName << " " << minName << endl;
    return 0;
}
发表于 2019-12-02 14:07:10 回复(0)

PAT、牛客网通过代码

#include<iostream>
using namespace std;
int main(){
    int N;
    int birth;
    string date;
    string name;
    int max=18140906,min=20140906;
    int maxIndex,minIndex;
    string maxName,minName; 
    cin>>N;
    int qualifiedNum=N;
    if(N>0){//没有这步判断 测试点3段错误 
        for(int i=0;i<N;i++){
            cin>>name>>date;
            birth=stoi(date.substr(0,4))*10000+stoi(date.substr(5,2))*100+stoi(date.substr(8,2));
            //谁的出生日期的整数值,小的最小,大的最大 
            if(birth>20140906||birth<18140906){//不在合法范围 
                //birth=0;//不合法生日置零 
                qualifiedNum--;//合法数字-- 
            }else{//在合法范围 
                if(max<birth){//最大值 
                    max=birth;
                    maxIndex=i;
                    maxName=name;
                }
                if(min>birth){//最小值 
                    min=birth;
                    minIndex=i;
                    minName=name;
                }    
            }
        } 
        if(qualifiedNum==0){//如果所有数据都不合法 输出0,否则测试点3格式错误 
            cout<<"0";
            return 0;
        }
        cout<<qualifiedNum<<" "<<minName<<" "<<maxName;
    } 
    return 0;
}
发表于 2019-08-13 18:04:00 回复(0)
#include <iostream>
#include <string>
//#include<string.h>
#include<list>
using namespace std;

string String2int(string it)
{     string sub;     int i = it.find(" ", 0);     sub = it.substr(i + 1, it.size() - i - 1);     int j = sub.find_first_of("/", 0);     sub.erase(j, 1);     int z = sub.find("/", 0);     sub.erase(z, 1);     return sub;
}

int  main()
{     int N;     cin >> N;     cin.get();     list<string> str;     while (N>0)     {         string tmp;         getline(cin, tmp);         str.push_back(tmp);         N--;     }     for (list<string>::iterator it = str.begin();it != str.end();)     {         string sub = String2int(*it);         if (stoi(sub)>20140906||stoi(sub)<18140906)         {             str.erase(it++);         }         else         {             it++;         }     }     cout << str.size();     string max, min;     //max = min = "20140906";     bool flag = false;     for (list<string>::iterator it = str.begin();it != str.end();it++)     {         string sub = String2int(*it);         if (!flag) {             min = max = sub;             flag = true;         }                      else         {             //max = min = sub;             if (stoi(max)>stoi(sub))             {                 max = sub;             }             else if (stoi(min)<stoi(sub))             {                 min = sub;             }         }              }     //bool tag = false;     for (list<string>::iterator it = str.begin();it != str.end();it++)     {         string sub = String2int(*it);         int i = it->find(" ", 0);         if (stoi(max)==stoi(sub))         {             cout <<" "<< it->substr(0, i);         }     }     for (list<string>::iterator it = str.begin();it != str.end();it++)     {         string sub = String2int(*it);         int i = it->find(" ", 0);         if (stoi(min) == stoi(sub))         {             cout << " " << it->substr(0, i);         }     }     cout << endl;     system("pause");     return 0;
}
比较通俗易懂的代码,不过代码量有点大,思路简单直白
发表于 2019-01-24 20:48:11 回复(0)
#在输入的过程中进行查找,不用保存下来。节省空间
try:
    while True:
        num = int(input())
        pastDays = '1814/09/06'    #初始化最早的出生日期
        nowDays = '2014/09/06'     #最晚的生日
        young = '1814/09/06'       #初始化年轻人的生日为最老
        elder = '2014/09/06'       #初始化老年人的生日为最年轻
        legal = 0
        for i in range(num):       #输入中比较
            temp = input().split() 
            if pastDays <= temp[1] <= nowDays:
                legal += 1
                if temp[1] > young:
                    youngName = temp[0]
                    young = temp[1]
                if temp[1] < elder:
                    elder = temp[1]
                    elderName = temp[0]
        print("%d %s %s" % (legal,elderName,youngName))
except Exception:
    pass

编辑于 2018-09-21 18:18:32 回复(0)
创建结构体
比较字符串
vector 排序
发表于 2017-04-21 20:36:13 回复(0)
#include <iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
typedef struct node
{
	string name;
	string date;
	int age;
	bool test()
	{
		bool sta;
		int sum = 0, t;
		for (auto c : date)
		{
			if (c >= '0'&&c <= '9')
				sum = sum * 10 + c - '0';		
		}
		age = sum;
		if (20140906 - sum <= 2000000 && sum < 20140906)
			sta = true;
		else
			sta = false;
		return sta;
	}
}node;
bool cmp(const node& x, const node& y)
{
	return x.age < y.age;
}
int main()
{		
	int length;
	while (cin >> length)
	{
		node n;
		vector<node> data;
		for (int i = 0; i < length; i++)
		{
			cin >> n.name >> n.date;
			if (n.test() == true)
				data.push_back(n);
		}
		sort(data.begin(), data.end(), cmp);
		cout << data.size() << " " << data[0].name << " " << data[data.size() - 1].name << endl;
	}
	return 0;
}

发表于 2017-04-19 21:01:56 回复(1)

#include<iostream>
#include<string.h>
using namespace std;
 
// PAT乙级人口普查(20)
bool timeCompare(chartime1[11],chartime2[11]);
intmain()
{
    intN,i,cnt=0;
    cin>>N;
    charnames[10],OldName[10],YoungName[10];
    chartimes[11],OldTime[11]="1814/09/05",YoungTime[11]="2015/09/07";
    charStartTime[11]="1814/09/05",FinishTime[11]="2015/09/07";
    for(i=0;i<N;i++){
        cin>>names>>times;
        if((timeCompare(times,StartTime)) &&(timeCompare(FinishTime,times))){
            cnt++;
            //find the oldest one
            if(timeCompare(YoungTime,times)){
                strcpy(YoungTime,times);
                strcpy(OldName,names);
            }
            //find the youngest one
            if(timeCompare(times,OldTime)){
                strcpy(OldTime,times);
                strcpy(YoungName,names);
            }
        }
    }
    if(cnt>0)
        cout<<cnt<<" "<<OldName<<" "<<YoungName<<endl;
    else
        cout<<"0";
    return0;
}
//compare the times
bool timeCompare(chartime1[11],chartime2[11])
{
    //time1 > time2 return true;
    inti;
    for(i=0;i<10;i++){
        if(time1[i] - time2[i] > 0)
            returntrue;
        if(time1[i] - time2[i] < 0)
            returnfalse;
    }
    returnfalse;
}

发表于 2017-01-15 17:02:44 回复(0)
import java.util.Scanner;
public class Main {
	private static final int TODAY = 20140906;
	private static final int LIMIT = 18140906;
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int max = Integer.MIN_VALUE;
		int min = Integer.MAX_VALUE;
		String eldest = null;
		String youngest = null;
		int count = 0;
		while(--n>=0){
			String name = in.next();
			String date = in.next();
			String[] d = date.split("/");
			int time = Integer.parseInt(d[0]);
			time = time*100+(d[1].charAt(0)-'0')*10+(d[1].charAt(1)-'0');
			time = time*100+(d[2].charAt(0)-'0')*10+(d[2].charAt(1)-'0');
			if(time>TODAY)
				continue;
			if(time<LIMIT)
				continue;
			count++;
			if(time>max){
				max = time;
				youngest = name;
			}
			if(time<min){
				min = time;
				eldest = name;
			}
		}
		System.out.println(count+" "+eldest+" "+youngest);
	}
}
编辑于 2016-06-10 21:58:05 回复(0)
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
struct people {
	string name;
	int y, m, d;
	bool operator <(const people& l)const
	{
		if (y<l.y)
			return true;
		if (y == l.y)
		{
			if (m<l.m)
				return true;
			if (m == l.m)
				return d<l.d;
			return false;
		}
		return false;
	}
};
people a[100005];
int main()
{
	int n, i = 0, y, m, d;
	string name, tmp, tmp1, tmp2, tmp3;
	cin >> n;
	while (n--)
	{
		cin >> name >> tmp;
		tmp1 = tmp.substr(0, 4);
		tmp2 = tmp.substr(5, 2);
		tmp3 = tmp.substr(8, 2);
		y = (tmp1[0] - '0') * 1000 + (tmp1[1] - '0') * 100 + (tmp1[2] - '0') * 10 + tmp1[3] - '0';
		m = (tmp2[0] - '0') * 10 + tmp2[1] - '0';
		d = (tmp3[0] - '0') * 10 + tmp3[1] - '0';
		if (y > 2014 || y < 1814)
			continue;
		else if (y == 2014 || y == 1814)
		{
			if (y == 2014)
			{
				if (m > 9)
					continue;
				else if (m == 9)
				{
					if (d > 6)
						continue;
				}
			}
			else
			{
				if (m < 9)
					continue;
				else if (m == 9)
				{
					if (d < 6)
						continue;
				}
			}
		}
		a[i].y = y;
		a[i].m = m;
		a[i].d = d;
		a[i].name = name;
		i++;
	}
	sort(a, a + i);
	cout << i << " " << a[0].name << " " << a[i - 1].name;
	return 0;
}

发表于 2016-02-25 12:29:34 回复(0)
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;

int main()
{
	int n,cnt=0,max_i=-1,min_i=-1;
	cin>>n;
	string name[100000],birthday[100000];
	string oldday="2014/09/06",youngday="1814/09/06";
//和总是把max初始化为最小道理一样 
	for(int i=0;i<n;i++)
	{
		cin>>name[i]>>birthday[i];
		
		if(birthday[i]>="1814/09/06" && birthday[i]<="2014/09/06")
		{
				cnt++;	
			if(birthday[i]>=youngday)//在合法的情况下查找最大和最小 
			{
				youngday=birthday[i];
				min_i=i;
			}
			if(birthday[i]<=oldday)
			{
				oldday=birthday[i];
				max_i=i;
			}	
		}
	 } 
	
	 if(cnt>0)
		{
			cout<<cnt<<" ";
			cout<<name[max_i]<<" "<<name[min_i];
		 } 
	else
		 cout<<"0";
	return 0;
}

发表于 2015-11-23 23:40:48 回复(0)
啥头像
#include <iostream>

using namespace std;

int main()
{
    ios::sync_with_stdio(false);
    int N; cin >> N;
    string name, str;
    string minStr="z", minName="";
    string maxStr="", maxName="";
    string start = "1814/09/06";
    string end = "2014/09/06";
    int counts = 0;
    for(int i=0; i<N; i++) {
        cin >> name >> str;
        if(str>=start && str<=end) {
            counts++;
            if(minStr > str) {
                minStr = str;
                minName = name;
            }
            if(maxStr < str) {
                maxStr = str;
                maxName = name;
            }
        }
    }
    cout << counts << " " << minName << " " << maxName << endl;
    return 0;
}


发表于 2015-10-20 21:05:48 回复(15)
转换成数字就很好处理。
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
using namespace std;
struct student{
       int sum;
       string name;
}stu[100001];
bool cmp(student a,student b)
{
     return a.sum<b.sum;
}
int main()
{
    int n,k,r=0;
    int y,d,m;
    char str[10];
    cin>>n;
    for(int i=0;i<n;i++)
     {scanf("%s %d/%d/%d",&str,&y,&m,&d);
      k=10000*y+100*m+d;
      if (k<=20140906&&20140906-k<=2000000)
       {stu[r].name=str;
        stu[r].sum=k;
        r++;}
     }
    sort(stu,stu+r,cmp);
    cout<<r<<" "<<stu[0].name<<" "<<stu[r-1].name;
    system("pause");
}
发表于 2017-08-20 17:44:02 回复(0)