工作室课题

练习

前10名

问题描述:
数据很多,但我们经常只取前几名,比如奥运只取前3名。现在我们有n个数据,请按从大到小的顺序,输出前10个名数据。
输入要求:
两行。
第一行一个整数n,表示要对多少个数据
第二行有n个整数,中间用空格分隔。表示n个数据。
输出要求:
一行,按从大到小排列的前10个数据,每个数据之间用一个空格隔开。
Sample Input 1
26
54 27 87 16 63 40 40 22 61 6 57 70 0 42 11 50 13 5 56 7 8 86 56 91 68 59
Sample Output 1
91 87 86 70 68 63 61 59 57 56
HINT:时间限制:1.0s 内存限制:256.0MB
10<=n<=200,各个整数不超出整型范围
代码python

n = int(input())
li = list(map(int, input().split()))//先转换成list,然后利用map函数进行输入,split()函数是以口号里的内容作为分隔符取字符串,不写着默认为空格
li.sort(reverse=True)
for i in range(0,10):
    print(li[i],end=" ")

身份证排序

问题描述:
安全局搜索到了一批(n个)身份证号码,希望按出生日期对它们进行从大到小排序,如果有相同日期,则按身份证号码大小进行排序。身份证号码为18位的数字组成,出生日期为第7到第14位
输入要求:
第一行一个整数n,表示有n个身份证号码
余下的n行,每行一个身份证号码。
输出要求:
按出生日期从大到小排序后的身份证号,每行一条
Sample Input 1
5
466272307503271156
215856472207097978
234804580401078365
404475727700034980
710351408803093165

Sample Output 1
404475727700034980
234804580401078365
215856472207097978
710351408803093165
466272307503271156

HINT:时间限制:1.0s 内存限制:256.0MB
n<=100000
代码python

def myg(b)://函数myg用来排序全部身份证号
    return int(b)
def myf(b)://函数myf用来排序生日
    return int(b[6:14])//截断的时候需要注意,左闭右开
n=int(input())
a=[input() for i in range(n)]//循环输入
a.sort(key=myg,reverse=True)
a.sort(key=myf,reverse=True)//sort中reverse = True降序,reverse = False 升序(默认)
for i in range(n):
    print(a[i],end="\n")

班级排名

问题描述:
达达在陶陶的影响下,也对学习慢慢的产生了兴趣。
他在每次考试之后,都会追着老师问,自己在班级的总名次是多少。考试一多,老师也不耐烦了,于是他给了达达所有人的成绩,让他自己去算出自己的排名。
可人太多了,达达也无法立即算出来,于是他想让你帮帮他。
输入要求
第一行为一个整数N,代表班级的学生总数。
接下来N行,每行一个字符串,代表一个学生的姓名,第一行总是DaDa。
接下来一行一个整数M,代表一共有M次考试。
每次考试有N行,每行有以一个空格分隔的一个正整数S和一个字符串P,代表名字为P的学生在这次考试中得了S分。
输出要求:
一共M行,每行一个整数,代表达达在班级里的排名,排名是这一次考试过后的所有考试总分排名,如果达达和别人并列,达达总是排在前面。
Sample Input 1
3
DaDa
A
B
2
49 DaDa
49 A
48 B
80 A
85 B
83 DaDa

Sample Output 1
1 2

HINT:时间限制:1.0s 内存限制:256.0MB
代码python

from operator import itemgetter

N = eval(input())//保证输入的为数字

Stu = {}//新建一个字典,用于存储学生姓名和分数
for i in range(N):
    Stu[input()] = 0

M = eval(input())

for i in range(M):
    for k,v in Stu.items()://键值都进入循环
        tmp = input().split()
        if tmp[1] not in Stu://不在,则直接赋值
            Stu[tmp[1]] = int(tmp[0])
        else:
            Stu[tmp[1]] += int(tmp[0])

    test = []

    for k, v in Stu.items():
        if k == 'DaDa':
            test.append([v, k, 1])
        else:
            test.append([v, k ,0])

    test.sort(key = itemgetter(0,2),reverse=True)
    for j in range(N):
        if 'DaDa' in test[j]:
            print(j+1)

冒泡排序

问题描述:
考虑冒泡排序的一种实现。
bubble-sort (A[], n)

round = 0
while A is not sorted

round := round + 1
for i := 1 to n - 1

if (A[i] > A[i + 1])

swap(A[i], A[i + 1])
求1 … n的排列中,有多少个排列使得A被扫描了K遍,亦即算法结束时round == K。
答案模20100713输出。

输入要求:
输入包含多组数据。每组数据为一行两个整数N,K。
输出要求:
对每组数据,输出一行一个整数表示答案
Sample Input 1
3
3 0
3 1
3 2
Sample Output 1
1
3
2

HINT:时间限制:1.0s 内存限制:256.0MB
T <= 10 ^ 5。
1 <= K < N < 10 ^ 6。
代码c++

#include <cstdio>
#include <iostream>
using namespace std;
const int mod = 20100713;
typedef long long ll;
const int N = 1e6+10;
ll f[N];
ll quick(ll a,ll n){
 ll ans = 1;
 while(n){
  if(n&1) ans = (ans*a)%mod;
  a = (a*a)%mod;
  n>>=1;
 }
 return ans;
} 

void init(){
 f[0] = f[1] = 1;
 for(int i = 2;i <= N-10;i++){
  f[i] = (f[i-1]*i)%mod;
 }
}
int main(){
 init();
 int t;scanf("%d",&t);
 ll n,k;
 while(t--){
  scanf("%lld%lld",&n,&k);
  ll ans = (f[k]*(quick(k+1,n-k)-quick(k,n-k)+mod)%mod)%mod;
  printf("%lld\n",ans);
 }
 return 0;
}

士兵排队

问题描述:
有N个士兵(1≤N≤26),编号依次为A,B,C,…,队列训练时,指挥官要把一些士兵从高到矮一次排成一行,但现在指挥官不能直接获得每个人的身高信息,只能获得“P1比P2高”这样的比较结果(P1、P2∈A,B,C,…,Z,记为 P1>P2),如”A>B”表示A比B高。
请编一程序,根据所得到的比较结果求出一种符合条件的排队方案。
(注:比较结果中没有涉及的士兵不参加排队)
输入要求:
比较结果从文本文件中读入(文件由键盘输入),每个比较结果在文本文件中占一行。
输出要求:
若输入数据无解,打印“No Answer!”信息,否则从高到矮一次输出每一个士兵的编号,中间无分割符,并把结果写入文本文件中,文件由键盘输入:
Sample Input 1
A>B
B>D
F>B
F<A
Sample Output 1
AFBD

HINT:时间限制:1.0s 内存限制:256.0MB
代码c++

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
//为拓扑排序
bool A[26];
set<int> out[26]; 
set<int> IN[26];  
int main()
{
    char a,b,c;
    while(cin>>a>>b>>c)
    {
        out[a - 'A'].insert(c - 'A');
        IN[c -'A'].insert(a - 'A');
        A[a - 'A'] = true;
        A[c - 'A'] = true;
    }   
    queue<int> q;
    for(int i=0;i<26;i++)
        if(IN[i].size() == 0 && A[i])   //把所有入度为0的点都入队
            q.push(i);
    char AN[26];
    int k = 0;
    while(! q.empty())
    {
        int j = q.front();
        set<int>::iterator it;
        for(it = out[j].begin();it!=out[j].end();it++)
        {
            int to = *it;       
            IN[to].erase(j);   //删除该点和他连的边
            if(IN[to].size()==0)
                q.push(to);
        }
        out[j].clear();   
        AN[++k] = (char) j + 'A';
        q.pop();
    }

    int i;
    for(int i=0;i<26;i++)
    {
        if(IN[i].size() > 0)
        {
            puts("No Answer!");
             return 0;
        }
    }
    for(int i=1;i<=k;i++) printf("%c",AN[i]);
}

测试

输如输出练习

问题描述:
按格式读入一个3位的整数、一个实数、一个字符 。
并按格式输出 一个整数占8位左对齐、一个实数占8位右对齐、一个字符 ,并用|隔开。
Sample Input 1
123456.789|a
Sample Output 1
123|456.8|a
代码c++

#include<stdio.h>
#include<iostream>
using namespace std;
int main()
{
    char a,b,c,d,e;
    double g;
    scanf("%c%c%c%lf%c%c",&a,&b,&c,&g,&d,&e);
    printf("%-8d|%8.1lf|%c",(a-'0')*100+(b-'0')*10+(c-'0'),g,e);//-为左对齐
    return 0;
}

3000米预测

问题描述:
3000米长跑时,围观党们兴高采烈地预测着最后的排名。因为他们来自不同的班,对所有运动员不一定都了解,于是他们分别对自己了解的一些运动员的实力作出了评估,即对部分运动员做了相对排名的预测,并且告诉了可怜留守的班长。因为无聊,于是他们就组团去打Dota去了。比赛结束后他们向班长询问最后的排名,但班长不记得了,只记得他们中哪些人的预测是正确的,哪些人的预测是错误的。他们想知道比赛的排名可能是什么。
输入要求:
第一行两个整数n, m,n为运动员数量,m为围观党数量。运动员编号从0到n-1。
接下来m行,每行为一个围观党的相对排名预测。每行第一个数c表示他预测的人数,后面跟着c个0~n-1的不同的数,表示他预测的运动员相对排名,最后还有一个数,0表示这个预测是错误的,1表示是正确的。
输出要求:
第一行一个数k为有多少种排名的可能。
下面k行,每行一个0~n-1的排列,为某一个可能的排名,相邻的数间用空格隔开。所有排名按字典序依次输出。
Sample Input 1
3 2
2 0 1 1
2 1 2 0
Sample Output 1
2
0 2 1
2 0 1
Sample Input 2
3 2
2 0 1 1
2 2 1 0
Sample Output 2
1
0 1 2

HINT:时间限制:1.0s 内存限制:256.0MB
1<=n<=10, 2<=c<=n, 1<=m<=10,保证数据合法,且答案中排名可能数不超过20000。对于一个排名序列,一个预测是正确的,当且仅当预测的排名的相对顺序是排名序列的一个子序列。一个预测是错误的,当且仅当这个预测不正确。
代码c++

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
using namespace std;
int str[15][15];
int ctr[15];
bool use[15];
int graph[20001][15];
int Size;
int m,n;
int Judge()
{
    int f_1=1;
    int f_2=1;
    for(int i=0; i<m; i++)
    {
        if(str[i][str[i][0]+1]==1&&f_1)
        {
            int j=1;
            for(int x=0; j<=str[i][0]&&x<n; x++)
            {
                if(str[i][j]==ctr[x])
                    j++;
            }
            if(j<str[i][0]+1)
                f_1=0;
        }
        else
        {
            int j=1;
            for(int x=0; j<=str[i][0]&&x<n; x++)
            {
                if(str[i][j]==ctr[x])
                    j++;
            }
            if(j==str[i][0]+1)
                f_2=0;

        }
        if(!f_1||!f_2)
            break;
    }

        if(f_1&&f_2)
            return 1;
        else
            return 0;

}
void DFS(int x)
{
    if(x==n&&Judge())
    {
        for(int i=0; i<n; i++)
        {
            graph[Size][i]=ctr[i];
        }
            Size++;


    }
    if(x<n)
    {
        for(int i=0; i<n; i++)
        {
            if(use[i])
            {
                ctr[x]=i;
                use[i]=false;
                DFS(x+1);
                use[i]=true;
            }
        }
    }
}
int main()
{

    while(cin>>n>>m)
    {


        for(int i=0; i<m; i++)
        {
            cin>>str[i][0];
            for(int j=1; j<=str[i][0]+1; j++)
            {
                cin>>str[i][j];
            }

        }
        memset(use,true,sizeof(use));
        Size=0;
        DFS(0);
        cout<<Size<<endl;
        for(int i=0; i<Size; i++)
        {
            for(int j=0; j<n; j++)
            {
                cout<<graph[i][j]<<" ";
            }
            cout<<endl;
        }
    }
    return 0;
}

选择排序

问题描述:
选择排序,顾名思义,是将若干个元素按其大小关系排出一个顺序。形式化描述如下:有n个元素a[1],a[2],…,a[n],从小到大排序就是将它们排成一个新顺序a[i[1]]<a[i[2]]<…<a[i[n]]
i[k]为这个新顺序。
选择排序的思想极其简单,每一步都把一个最小元素放到前面,如果有多个相等的最小元素,选择排位较考前的放到当前头部。还是那个例子:{3 1 5 4 2}:
第一步将1放到开头(第一个位置),也就是交换3和1,即swap(a[0],a[1])得到{1 3 5 4 2}
第二步将2放到第二个位置,也就是交换3和2,即swap(a[1],a[4])得到{1 2 5 4 3}
第三步将3放到第三个位置,也就是交换5和3,即swap(a[2],a[4])得到{1 2 3 4 5}
第四步将4放到第四个位置,也就是交换4和4,即swap(a[3],a[3])得到{1 2 3 4 5}
第五步将5放到第五个位置,也就是交换5和5,即swap(a[4],a[4])得到{1 2 3 4 5}
输入n个整数,输出选择排序的全过程。
要求使用递归实现。
输入要求:
第一行一个正整数n,表示元素个数
第二行为n个整数,以空格隔开
输出要求:
共n行,每行输出第n步选择时交换哪两个位置的下标,以及交换得到的序列,格式:
swap(a[i],a[j]):a[0] … a[n-1]
i和j为所交换元素的下标,下标从0开始,最初元素顺序按输入顺序。另外请保证i<=j
a[0]…a[n-1]为交换后的序列,元素间以一个空格隔开
Sample Input 1
5
4 3 1 1 2
Sample Output 1
swap(a[0], a[2]):1 3 4 1 2
swap(a[1], a[3]):1 1 4 3 2
swap(a[2], a[4]):1 1 2 3 4
swap(a[3], a[3]):1 1 2 3 4
swap(a[4], a[4]):1 1 2 3 4

HINT:时间限制:1.0s 内存限制:256.0MB
代码c++

#include<stdio.h>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
int NUM[100+10];
void sort(int k,int v){   
    if(k<=v){  
        int t=k;
        int min=NUM[k];
        for(int i=k+1;i<=v;i++){  //找出l-r中最小值,并与l交换 
            if(NUM[i]<min){
                t=i;
                min=NUM[i];
            }
        }
        cout<<"swap(a["<<k<<"], a["<<t<<"]):";
        swap(NUM[k],NUM[t]);
        for(int i=0;i<=v;i++){
            cout<<NUM[i];
            if(i!=v){
                cout<<" ";    
            }else{
                cout<<endl;
            }
        }
        sort(k+1,v);   //前面为有序序列,后面无  
    }
}    
int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        scanf("%d",&NUM[i]);
    }
    sort(0,n-1);
    return 0;
}

色盲的民主

问题描述:
n个色盲聚在一起,讨论一块布的颜色。尽管都是色盲,却盲得各不相同。每个人都有自己的主张,争论不休。最终,他们决定采取民主投票的方式决定布的颜色,不管布同不同意。某种颜色用字符串表示(字符串为颜色单词或词组,也就是可能有被空格隔开的两个单词组成的颜色词组),只要字符串不同,程序即判断颜色不同。现在给出这n个人所选择的颜色,输出最有可能的颜色(也就是获得投票最多的颜色),如果有多个颜色获得了最多的投票,则将它们按字典序分行全部输出。
输入要求:
第一行一个正整数n,表示色盲的人数
接下来n行,每行一句话
输出要求:
若干行,获得投票最多的颜色,按字典序输
Sample Input 1
5
red
blue
black
black
blue
Sample Output 1
black
blue

HINT:时间限制:1.0s 内存限制:256.0MB
代码python

n = int(input())
res = [input() for i in range(n)]
apper_time = {}//新建立一个字典
for i in res://将每个人的选择进行统计
    if i in apper_time:
        apper_time[i] += 1
    else:
        apper_time[i] = 1
max_time = []//新建一个列表,将作为输出的集合
max_value = max(apper_time.values())先把最大的取出来
for k,v in apper_time.items()://键值开始循环,找出最大的值一个或多个
    if v == max_value:
        max_time.append(k)
max_time.sort()//按照字典排序
for i in range(len(max_time)):
    print(max_time[i])

插入排序

问题描述:
插入排序,顾名思义,是将若干个元素按其大小关系排出一个顺序。形式化描述如下:有n个元素a[1],a[2],…,a[n],从小到大排序就是将它们排成一个新顺序a[i[1]]<a[i[2]]<…<a[i[n]]
i[k]为这个新顺序。
插入排序,顾名思义,是通过插入操作完成排序。其直觉和方法来源于打牌时安排牌的方法。每次摸起一张牌,你都会将其插入到现在手牌中它按顺序应在的那个位置。插入排序每一步都类似这个摸牌过程。比如现在有整数数组:{3, 1, 5, 4, 2}
第一步:插入3 得到新序列{3}
第二步:插入1 得到新序列{1 3}
第三步:插入5 得到新序列{1 3 5}
第四步:插入4 得到新序列{1 3 4 5}
第五步:插入2 得到新序列{1 2 3 4 5}
为了看程序中如何完成插入过程,我们以第五步为例:
初始时:1 3 4 5 2
将2存入临时变量tmp
将下标j指向2之前的元素5,然后根据tmp和a[j]的大小关系决定该元素是否应该后移。如果a[j]>tmp,则将a[j]后移到a[j+1],序列变成1 3 4 5 5。
将下标j前移
判断a[j]>tmp,后移a[j]到a[j+1],得到1 3 4 4 5
将下标j前移
判断a[j]>tmp,后移a[j]到a[j+1],得到1 3 3 4 5
因为a[j]<=tmp,所以将tmp放回a[j+1],得到 1 2 3 4 5
现在,输入n个整数,根据以上算法,输出插入排序的全过程。
输入要求:
第一行一个正整数n,表示元素个数
第二行为n个整数,以空格隔开
输出要求:
有n个元素,因此输出部分分为n个部分,每个部分开头行为:Insert element[i],i为第几个元素。然后对于每一个部分,输出该部分该元素在插入排序过程中的每一步产生的新序列,初始时的序列以Init:打头,然后每一步后移数组元素后的元素序列以Move back:打头,最后得到的最终结果序列以Final:打头。序列元素间以一个空格隔开。示例请看样例输出。每一个部分的Insert element[i]之后的每一步的输出行之前要缩进两格,即输出两个空格

Sample Input 1
5
3 1 5 4 2
Sample Output 1
Insert element[1]:
Init:3
Final:3
Insert element[2]:
Init:3 1
Move back:3 3
Final:1 3
Insert element[3]:
Init:1 3 5
Final:1 3 5
Insert element[4]:
Init:1 3 5 4
Move back:1 3 5 5
Final:1 3 4 5
Insert element[5]:
Init:1 3 4 5 2
Move back:1 3 4 5 5
Move back:1 3 4 4 5
Move back:1 3 3 4 5
Final:1 2 3 4 5

HINT:时间限制:1.0s 内存限制:256.0MB
代码python

def Insert(A):
    Init = []
    for a in range(0,len(A))://0到A的长度循环
        print("Insert element[%d]:"%(a+1))
        Init.append(A[a])
        print("  Init:"+' '.join(str(i) for i in Init))//join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。
        key = Init[a]
        j = a-1
        while j>=0 and key<Init[j]:
            Init[j+1] = Init[j]
            print("  Move back:"+' '.join(str(i) for i in Init))
            j -= 1
        Init[j+1] = key
        print("  Final:"+' '.join(str(i) for i in Init))
if __name__ == "__main__":
    n = int(input())
    A = list(map(int,input().split(" ")))
    Insert(A)

相关链接:

  1. sort方法
  2. 比较字典中的最大值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值