Python\C++| CCFCSP 第二题(全)

5 篇文章 0 订阅
5 篇文章 1 订阅

问题描述

试题编号:201709-2
试题名称:公共钥匙盒
时间限制:1.0s
内存限制:256.0MB
问题描述:

问题描述

  有一个学校的老师共用N个教室,按照规定,所有的钥匙都必须放在公共钥匙盒里,老师不能带钥匙回家。每次老师上课前,都从公共钥匙盒里找到自己上课的教室的钥匙去开门,上完课后,再将钥匙放回到钥匙盒中。
  钥匙盒一共有N个挂钩,从左到右排成一排,用来挂N个教室的钥匙。一串钥匙没有固定的悬挂位置,但钥匙上有标识,所以老师们不会弄混钥匙。
  每次取钥匙的时候,老师们都会找到自己所需要的钥匙将其取走,而不会移动其他钥匙。每次还钥匙的时候,还钥匙的老师会找到最左边的空的挂钩,将钥匙挂在这个挂钩上。如果有多位老师还钥匙,则他们按钥匙编号从小到大的顺序还。如果同一时刻既有老师还钥匙又有老师取钥匙,则老师们会先将钥匙全还回去再取出。
  今天开始的时候钥匙是按编号从小到大的顺序放在钥匙盒里的。有K位老师要上课,给出每位老师所需要的钥匙、开始上课的时间和上课的时长,假设下课时间就是还钥匙时间,请问最终钥匙盒里面钥匙的顺序是怎样的?

输入格式

  输入的第一行包含两个整数NK
  接下来K行,每行三个整数wsc,分别表示一位老师要使用的钥匙编号、开始上课的时间和上课的时长。可能有多位老师使用同一把钥匙,但是老师使用钥匙的时间不会重叠。
  保证输入数据满足输入格式,你不用检查数据合法性。

输出格式

  输出一行,包含N个整数,相邻整数间用一个空格分隔,依次表示每个挂钩上挂的钥匙编号。

样例输入

5 2
4 3 3
2 2 7

样例输出

1 4 3 2 5

样例说明

  第一位老师从时刻3开始使用4号教室的钥匙,使用3单位时间,所以在时刻6还钥匙。第二位老师从时刻2开始使用钥匙,使用7单位时间,所以在时刻9还钥匙。
  每个关键时刻后的钥匙状态如下(X表示空):
  时刻2后为1X345;
  时刻3后为1X3X5;
  时刻6后为143X5;
  时刻9后为14325。

样例输入

5 7
1 1 14
3 3 12
1 15 12
2 7 20
3 18 12
4 21 19
5 30 9

样例输出

1 2 3 5 4

评测用例规模与约定

  对于30%的评测用例,1 ≤ NK ≤ 10, 1 ≤ w ≤ N, 1 ≤ sc ≤ 30;
  对于60%的评测用例,1 ≤ NK ≤ 50,1 ≤ w ≤ N,1 ≤ s ≤ 300,1 ≤ c ≤ 50;
  对于所有评测用例,1 ≤ NK ≤ 1000,1 ≤ w ≤ N,1 ≤ s ≤ 10000,1 ≤ c ≤ 100。

 

import sys
a,b=sys.stdin.readline().split()
a=int(a)
b=int(b)
work=list(range(1,a+1))
#print(work)
thing=[]
timetable={}
for i in range(0,b):
    k=sys.stdin.readline().split()
    k=[int(x) for x in k]
    k[2] += k[1]
    timetable[k[1]]=0
    timetable[k[2]]=0
    thing.append(k)
thing.sort(key=lambda x:(x[1],x[0]))
thing.sort(key=lambda x:(x[2],x[0]))
maxtime=thing[b-1][2]
for c in range(1,maxtime+1):
    if(c in timetable):
        for th in thing:
            if(th[2] == c):
                for index in range(0,a):
                    if(work[index]==0):
                        work[index]=th[0]
                        break
        #print(work)
            if (th[1] == c):
                work[work.index(th[0])] = 0
    #print(c)
    #print(work)
for kk in work:
    sys.stdout.write(str(kk)+' ')

 

试题编号:201312-2
试题名称:ISBN号码
时间限制:1.0s
内存限制:256.0MB
问题描述:

问题描述

  每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字、1位识别码和3位分隔符,其规定格式如“x-xxx-xxxxx-x”,其中符号“-”是分隔符(键盘上的减号),最后一位是识别码,例如0-670-82162-4就是一个标准的ISBN码。ISBN码的首位数字表示书籍的出版语言,例如0代表英语;第一个分隔符“-”之后的三位数字代表出版社,例如670代表维京出版社;第二个分隔之后的五位数字代表该书在出版社的编号;最后一位为识别码。
  识别码的计算方法如下:
  首位数字乘以1加上次位数字乘以2……以此类推,用所得的结果mod 11,所得的余数即为识别码,如果余数为10,则识别码为大写字母X。例如ISBN号码0-670-82162-4中的识别码4是这样得到的:对067082162这9个数字,从左至右,分别乘以1,2,…,9,再求和,即0×1+6×2+……+2×9=158,然后取158 mod 11的结果4作为识别码。
  编写程序判断输入的ISBN号码中识别码是否正确,如果正确,则仅输出“Right”;如果错误,则输出是正确的ISBN号码。

输入格式

  输入只有一行,是一个字符序列,表示一本书的ISBN号码(保证输入符合ISBN号码的格式要求)。

输出格式

  输出一行,假如输入的ISBN号码的识别码正确,那么输出“Right”,否则,按照规定的格式,输出正确的ISBN号码(包括分隔符“-”)。

样例输入

0-670-82162-4

样例输出

Right

样例输入

0-670-82162-0

样例输出

0-670-82162-4

 

其实很简单的题 做麻烦了 不过用到了大佬的STL实现的split (java和Python都可以用 然而c++没有)

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

vector<string> split(const string &s, const string &seperator)
{
    vector<string> result;
    typedef string::size_type string_size;
    string_size i = 0;

    while(i != s.size())
    {
        //找到字符串中首个不等于分隔符的字母;
        int flag = 0;
        while(i != s.size() && flag == 0)
        {
            flag = 1;
            for(string_size x = 0; x < seperator.size(); ++x)
                if(s[i] == seperator[x])
                {
                    ++i;
                    flag = 0;
                    break;
                }
        }
        //找到又一个分隔符,将两个分隔符之间的字符串取出;
        flag = 0;
        string_size j = i;
        while(j != s.size() && flag == 0)
        {
            for(string_size x = 0; x < seperator.size(); ++x)
                if(s[j] == seperator[x])
                {
                    flag = 1;
                    break;
                }
            if(flag == 0)
                ++j;
        }
        if(i != j)
        {
            result.push_back(s.substr(i, j-i));
            i = j;
        }
    }
    return result;
}
int main()
{
    string  aa;
    while(cin>>aa)
    {
        vector<string> v = split(aa, "-");
         int tt=0;
          int c=1;
        for(vector<string>::size_type i = 0; i != v.size()-1; ++i)
        {
            for(int j=0;j<v[i].length();j++)
            {tt+=(int(v[i][j])-48)*c;
            tt%=11;
            c++;
            }
        }
        int cc=0;
         for(int j=0;j<v[3].length();j++)
            {
                cc*=10;
                cc+=(int(v[3][j])-48);
            }
        if(tt==10&&v[3]=="X")
            cout<<"Right"<<endl;
        else if(tt==cc&&tt!=10)
            cout<<"Right"<<endl;
        else if (tt==10)
        cout<<v[0]<<"-"<<v[1]<<"-"<<v[2]<<"-"<<"X"<<endl;
        else
            cout<<v[0]<<"-"<<v[1]<<"-"<<v[2]<<"-"<<tt<<endl;
    }
    return 0;
}
试题编号:201403-2
试题名称:窗口
时间限制:1.0s
内存限制:256.0MB
问题描述:

问题描述

  在某图形操作系统中,有 N 个窗口,每个窗口都是一个两边与坐标轴分别平行的矩形区域。窗口的边界上的点也属于该窗口。窗口之间有层次的区别,在多于一个窗口重叠的区域里,只会显示位于顶层的窗口里的内容。
  当你点击屏幕上一个点的时候,你就选择了处于被点击位置的最顶层窗口,并且这个窗口就会被移到所有窗口的最顶层,而剩余的窗口的层次顺序不变。如果你点击的位置不属于任何窗口,则系统会忽略你这次点击。
  现在我们希望你写一个程序模拟点击窗口的过程。

输入格式

  输入的第一行有两个正整数,即 N 和 M。(1 ≤ N ≤ 10,1 ≤ M ≤ 10)
  接下来 N 行按照从最下层到最顶层的顺序给出 N 个窗口的位置。 每行包含四个非负整数 x1, y1, x2, y2,表示该窗口的一对顶点坐标分别为 (x1, y1) 和 (x2, y2)。保证 x1 < x2,y1 2。
  接下来 M 行每行包含两个非负整数 x, y,表示一次鼠标点击的坐标。
  题目中涉及到的所有点和矩形的顶点的 x, y 坐标分别不超过 2559 和  1439。

输出格式

  输出包括 M 行,每一行表示一次鼠标点击的结果。如果该次鼠标点击选择了一个窗口,则输出这个窗口的编号(窗口按照输入中的顺序从 1 编号到 N);如果没有,则输出"IGNORED"(不含双引号)。

样例输入

3 4
0 0 4 4
1 1 5 5
2 2 6 6
1 1
0 0
4 4
0 5

样例输出

2
1
1
IGNORED

样例说明

  第一次点击的位置同时属于第 1 和第 2 个窗口,但是由于第 2 个窗口在上面,它被选择并且被置于顶层。
  第二次点击的位置只属于第 1 个窗口,因此该次点击选择了此窗口并将其置于顶层。现在的三个窗口的层次关系与初始状态恰好相反了。
  第三次点击的位置同时属于三个窗口的范围,但是由于现在第 1 个窗口处于顶层,它被选择。
  最后点击的 (0, 5) 不属于任何窗口。

#include <iostream>
#include <cstdio>
using namespace std;
struct node
{
    int x1,y1,x2,y2,id;
};
struct node xx[15];;
int main()
{
    int m,n;
    int a,b;
    while(~scanf("%d %d",&m,&n))
    {
        for(int i=0; i<m; i++)
        {
            scanf("%d %d %d %d",&xx[i].x1,&xx[i].y1,&xx[i].x2,&xx[i].y2);
            xx[i].id=i+1;
        }
        for(int j=0; j<n; j++)
        {
            scanf("%d %d",&a,&b);
            int f=0;
            for(int i=m-1; i>=0; i--)
            {
                if((a>=xx[i].x1&&b>=xx[i].y1&&a<=xx[i].x2&&b<=xx[i].y2))
                {
                    f=1;
                    struct node tmp;
                    tmp=xx[i];
                    for(int k=i; k<m-1; k++)
                        xx[k]=xx[k+1];
                    xx[m-1]=tmp;
                    break;
                }
            }
            if(f==0)
                cout<<"IGNORED"<<endl;
            else
                cout<<xx[m-1].id<<endl;
        }
    }
    return 0;
}
试题编号:201409-2
试题名称:画图
时间限制:1.0s
内存限制:256.0MB
问题描述:

问题描述

  在一个定义了直角坐标系的纸上,画一个(x1,y1)到(x2,y2)的矩形指将横坐标范围从x1到x2,纵坐标范围从y1到y2之间的区域涂上颜色。
  下图给出了一个画了两个矩形的例子。第一个矩形是(1,1) 到(4, 4),用绿色和紫色表示。第二个矩形是(2, 3)到(6, 5),用蓝色和紫色表示。图中,一共有15个单位的面积被涂上颜色,其中紫色部分被涂了两次,但在计算面积时只计算一次。在实际的涂色过程中,所有的矩形都涂成统一的颜色,图中显示不同颜色仅为说明方便。

  给出所有要画的矩形,请问总共有多少个单位的面积被涂上颜色。

输入格式

  输入的第一行包含一个整数n,表示要画的矩形的个数。
  接下来n行,每行4个非负整数,分别表示要画的矩形的左下角的横坐标与纵坐标,以及右上角的横坐标与纵坐标。

输出格式

  输出一个整数,表示有多少个单位的面积被涂上颜色。

样例输入

2
1 1 4 4
2 3 6 5

样例输出

15

评测用例规模与约定

  1<=n<=100,0<=横坐标、纵坐标<=100。

#include <iostream>
#include <cstring>
using namespace std;
int tt[105][105];
int main()
{
    int n;
    while(cin>>n)
    {
        memset(tt,0,sizeof(tt));
        int a,b,c,d;
        for(int i=0; i<n; i++)
        {
            cin>>a>>b>>c>>d;
            for(int i=a; i<c; i++)
                for(int j=b; j<d; j++)
                    tt[i][j]=1;
        }
       /* for(int i=0; i<=7; i++)
        {
            for(int j=0; j<=7; j++)
            {
                cout<<tt[i][j]<<" ";
            }
            cout<<endl;
        }*/
        int ans=0;
        for(int i=0; i<=100; i++)
            for(int j=0; j<=100; j++)
                if(tt[i][j])
                    ans++;
        cout<<ans<<endl;
    }
    return 0;
}
试题编号:201412-2
试题名称:Z字形扫描
时间限制:2.0s
内存限制:256.0MB
问题描述:

问题描述

  在图像编码的算法中,需要将一个给定的方形矩阵进行Z字形扫描(Zigzag Scan)。给定一个n×n的矩阵,Z字形扫描的过程如下图所示:

  对于下面的4×4的矩阵,
  1 5 3 9
  3 7 5 6
  9 4 6 4
  7 3 1 3
  对其进行Z字形扫描后得到长度为16的序列:
  1 5 3 9 7 3 9 5 4 7 3 6 6 4 1 3
  请实现一个Z字形扫描的程序,给定一个n×n的矩阵,输出对这个矩阵进行Z字形扫描的结果。

输入格式

  输入的第一行包含一个整数n,表示矩阵的大小。
  输入的第二行到第n+1行每行包含n个正整数,由空格分隔,表示给定的矩阵。

输出格式

  输出一行,包含n×n个整数,由空格分隔,表示输入的矩阵经过Z字形扫描后的结果。

样例输入

4
1 5 3 9
3 7 5 6
9 4 6 4
7 3 1 3

样例输出

1 5 3 9 7 3 9 5 4 7 3 6 6 4 1 3

评测用例规模与约定

  1≤n≤500,矩阵元素为不超过1000的正整数。

#include <iostream>
#include <cstring>
using namespace std;
int tt[505][505];
int n;
void solve()
{
    int nowx=0,nowy=0;
    cout<<tt[0][0]<<" ";
    int r=0;
    while(!(nowx==n-1&&nowy==n-1))
    {
        if(r==0)
        {
            if(nowy+1<=n-1)
                nowy+=1;
            else
                nowx+=1;
            cout<<tt[nowx][nowy]<<" ";
            r++;
            r%=4;
        }
        if(r==1)
        {
            while(1)
            {
                nowx+=1;
                nowy-=1;
                if(nowx<=n-1&&nowy<=n-1&&nowx>=0&&nowy>=0)
                    cout<<tt[nowx][nowy]<<" ";
                else
                    break;
            }
            nowx-=1;
            nowy+=1;
            r++;
            r%=4;
        }
        if(r==2)
        {
            if(nowx+1<=n-1)
                nowx+=1;
            else
                nowy+=1;
            cout<<tt[nowx][nowy]<<" ";
            r++;
            r%=4;
        }
        if(r==3)
        {
            while(1)
            {
                nowx-=1;
                nowy+=1;
                if(nowx<=n-1&&nowy<=n-1&&nowx>=0&&nowy>=0)
                    cout<<tt[nowx][nowy]<<" ";
                else
                    break;
            }
            nowx+=1;
            nowy-=1;
            r++;
            r%=4;
        }
    }
    cout<<endl;
}
int main()
{

    while(cin>>n)
    {
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
            {
                cin>>tt[i][j];
            }
        solve();
    }
    return 0;
}
试题编号:201503-2
试题名称:数字排序
时间限制:1.0s
内存限制:256.0MB
问题描述:

问题描述

  给定n个整数,请统计出每个整数出现的次数,按出现次数从多到少的顺序输出。

输入格式

  输入的第一行包含一个整数n,表示给定数字的个数。
  第二行包含n个整数,相邻的整数之间用一个空格分隔,表示所给定的整数。

输出格式

  输出多行,每行包含两个整数,分别表示一个给定的整数和它出现的次数。按出现次数递减的顺序输出。如果两个整数出现的次数一样多,则先输出值较小的,然后输出值较大的。

样例输入

12
5 2 3 3 1 3 4 2 5 2 3 5

样例输出

3 4
2 3
5 3
1 1
4 1

评测用例规模与约定

  1 ≤ n ≤ 1000,给出的数都是不超过1000的非负整数。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef struct node
{
    int id,num;
} tt;
tt xx[1005];
bool cmp(node a,node b)
{
    if(a.num!=b.num)
    return a.num>b.num;
    else
        return a.id<b.id;
}
int main()
{
    int n;
    while(cin>>n)
    {
        int yy[1005];
        int tmp;
        memset(yy,0,sizeof(yy));
        int minn=1005,maxn=-1;
        for(int i=0; i<n; i++)
        {
            scanf("%d",&tmp);
            minn=min(minn,tmp);
            maxn=max(maxn,tmp);
            yy[tmp]++;
        }
        int cnt=0;
        for(int i=minn;i<=maxn;i++)
             if(yy[i]>0)
        {
            xx[cnt].id=i;
            xx[cnt++].num=yy[i];
        }
        sort(xx,xx+cnt,cmp);
        for(int i=0;i<cnt; i++)
            cout<<xx[i].id<<" "<<xx[i].num<<endl;
    }
    return 0;
}
试题编号:201509-2
试题名称:日期计算
时间限制:1.0s
内存限制:256.0MB
问题描述:

问题描述

  给定一个年份y和一个整数d,问这一年的第d天是几月几日?
  注意闰年的2月有29天。满足下面条件之一的是闰年:
  1) 年份是4的整数倍,而且不是100的整数倍;
  2) 年份是400的整数倍。

输入格式

  输入的第一行包含一个整数y,表示年份,年份在1900到2015之间(包含1900和2015)。
  输入的第二行包含一个整数dd在1至365之间。

输出格式

  输出两行,每行一个整数,分别表示答案的月份和日期。

样例输入

2015
80

样例输出

3
21

样例输入

2000
40

样例输出

2
9

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int days[13]= {29,31,28,31,30,31,30,31,31,30,31,30,31};
int main()
{
    int year,day;
    while(cin>>year)
    {
        cin>>day;
        int f=0;
        if((year%4==0&&year%100!=0)||year%400==0)
            f=1;
        int now=0;
        int i=1;
        while(now<day)
        {
            if(i==2&&f==1)
                now+=days[0];
            else
                now+=days[i];
            i++;
        }
        if(i-1==2&&f==1)
            now-=days[0];
        else
            now-=days[i-1];
        cout<<i-1<<endl;
        cout<<day-now<<endl;
    }
    return 0;
}
试题编号:201512-2
试题名称:消除类游戏
时间限制:1.0s
内存限制:256.0MB
问题描述:

问题描述

  消除类游戏是深受大众欢迎的一种游戏,游戏在一个包含有nm列的游戏棋盘上进行,棋盘的每一行每一列的方格上放着一个有颜色的棋子,当一行或一列上有连续三个或更多的相同颜色的棋子时,这些棋子都被消除。当有多处可以被消除时,这些地方的棋子将同时被消除。
  现在给你一个nm列的棋盘,棋盘中的每一个方格上有一个棋子,请给出经过一次消除后的棋盘。
  请注意:一个棋子可能在某一行和某一列同时被消除。

输入格式

  输入的第一行包含两个整数nm,用空格分隔,分别表示棋盘的行数和列数。
  接下来n行,每行m个整数,用空格分隔,分别表示每一个方格中的棋子的颜色。颜色使用1至9编号。

输出格式

  输出n行,每行m个整数,相邻的整数之间使用一个空格分隔,表示经过一次消除后的棋盘。如果一个方格中的棋子被消除,则对应的方格输出0,否则输出棋子的颜色编号。

样例输入

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

样例输出

2 2 3 0 2
3 4 5 0 4
2 3 2 0 3
0 0 0 4 4

样例说明

  棋盘中第4列的1和第4行的2可以被消除,其他的方格中的棋子均保留。

样例输入

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

样例输出

2 2 3 0 2
3 0 0 0 0
2 3 2 0 3
2 2 0 0 0

样例说明

  棋盘中所有的1以及最后一行的3可以被同时消除,其他的方格中的棋子均保留。

评测用例规模与约定

  所有的评测用例满足:1 ≤ nm ≤ 30。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int tt[35][35];
int ss[35][35];
int main()
{
   int n,m;
    while(cin>>n>>m)
    {
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                cin>>tt[i][j];
            memset(ss,0,sizeof(ss));
           for(int i=0;i<n;i++)
           {
                for(int j=1;j<m-1;j++)
                {
                    if(tt[i][j-1]==tt[i][j]&&tt[i][j]==tt[i][j+1])
                    {
                        ss[i][j]=1;
                        ss[i][j-1]=1;
                        ss[i][j+1]=1;
                    }
                }
           }
           for(int j=0;j<m;j++)
           {
               for(int i=1;i<n-1;i++)
                {
                    if(tt[i-1][j]==tt[i][j]&&tt[i][j]==tt[i+1][j])
                    {
                        ss[i][j]=1;
                        ss[i+1][j]=1;
                        ss[i-1][j]=1;
                    }
                }
           }
           for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                if(ss[i][j])
                tt[i][j]=0;
           for(int i=0; i<n; i++)
            {
                for(int j=0; j<m; j++)
                    cout<<tt[i][j]<<" ";
                cout<<endl;
            }
    }
    return 0;
}
试题编号:201604-2
试题名称:俄罗斯方块
时间限制:1.0s
内存限制:256.0MB
问题描述:

问题描述

  俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游戏。
  游戏在一个15行10列的方格图上进行,方格图上的每一个格子可能已经放置了方块,或者没有放置方块。每一轮,都会有一个新的由4个小方块组成的板块从方格图的上方落下,玩家可以操作板块左右移动放到合适的位置,当板块中某一个方块的下边缘与方格图上的方块上边缘重合或者达到下边界时,板块不再移动,如果此时方格图的某一行全放满了方块,则该行被消除并得分。
  在这个问题中,你需要写一个程序来模拟板块下落,你不需要处理玩家的操作,也不需要处理消行和得分。
  具体的,给定一个初始的方格图,以及一个板块的形状和它下落的初始位置,你要给出最终的方格图。

输入格式

  输入的前15行包含初始的方格图,每行包含10个数字,相邻的数字用空格分隔。如果一个数字是0,表示对应的方格中没有方块,如果数字是1,则表示初始的时候有方块。输入保证前4行中的数字都是0。
  输入的第16至第19行包含新加入的板块的形状,每行包含4个数字,组成了板块图案,同样0表示没方块,1表示有方块。输入保证板块的图案中正好包含4个方块,且4个方块是连在一起的(准确的说,4个方块是四连通的,即给定的板块是俄罗斯方块的标准板块)。
  第20行包含一个1到7之间的整数,表示板块图案最左边开始的时候是在方格图的哪一列中。注意,这里的板块图案指的是16至19行所输入的板块图案,如果板块图案的最左边一列全是0,则它的左边和实际所表示的板块的左边是不一致的(见样例)

输出格式

  输出15行,每行10个数字,相邻的数字之间用一个空格分隔,表示板块下落后的方格图。注意,你不需要处理最终的消行。

样例输入

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0
1 1 1 0 0 0 1 1 1 1
0 0 0 0 1 0 0 0 0 0
0 0 0 0
0 1 1 1
0 0 0 1
0 0 0 0
3

样例输出

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0
1 1 1 1 1 1 1 1 1 1
0 0 0 0 1 1 0 0 0 0

我用了一个超级暴力的办法   看了其他人写的真是简洁 模拟下落过程 只要没冲突就不断下降 还好数据量小

#include <iostream>

using namespace std;
int mapp[24][12];
int mapp2[24][12];
int xx[5][5];
int c;
void change()
{
    for(int i=5; i<=19; i++)
        for(int j=1; j<=10; j++)
        {
            mapp2[i][j]=mapp[i][j];
        }
}
bool check()
{
    for(int i=5; i<=19; i++)
        for(int j=1; j<=10; j++)
        {
            if(mapp2[i][j]==2)
                return false;
        }
    return true;
}
void process(int line)
{
    for(int i=line,x=1; x<=4&&i<=line+3; i++,x++)
        for(int j=c,y=1; y<=4&&j<=c+3; j++,y++)
        {
            mapp2[i][j]+=xx[x][y];
        }
}
int main()
{

    for(int i=5; i<=19; i++)
        for(int j=1; j<=10; j++)
        {
            cin>>mapp[i][j];
            mapp2[i][j]=mapp[i][j];
        }
        int maxn;
    for(int i=1; i<=4; i++)
        for(int j=1; j<=4; j++)
            {cin>>xx[i][j];
             if(xx[i][j])
                maxn=i;
            }
    cin>>c;
    int k;
    for(k=2;k<=19-maxn+1;k++)
    {
        process(k);
        if(check())
        {
            change();
        }
        else
            break;
    }
    change();
    process(k-1);
    for(int i=5; i<=19; i++)
    {
        for(int j=1; j<=10; j++)
        {
            cout<<mapp2[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}
试题编号:201609-2
试题名称:火车购票
时间限制:1.0s
内存限制:256.0MB
问题描述:

问题描述

  请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配。
  假设一节车厢有20排、每一排5个座位。为方便起见,我们用1到100来给所有的座位编号,第一排是1到5号,第二排是6到10号,依次类推,第20排是96到100号。
  购票时,一个人可能购一张或多张票,最多不超过5张。如果这几张票可以安排在同一排编号相邻的座位,则应该安排在编号最小的相邻座位。否则应该安排在编号最小的几个空座位中(不考虑是否相邻)。
  假设初始时车票全部未被购买,现在给了一些购票指令,请你处理这些指令。

输入格式

  输入的第一行包含一个整数n,表示购票指令的数量。
  第二行包含n个整数,每个整数p在1到5之间,表示要购入的票数,相邻的两个数之间使用一个空格分隔。

输出格式

  输出n行,每行对应一条指令的处理结果。
  对于购票指令p,输出p张车票的编号,按从小到大排序。

样例输入

4
2 5 4 2

样例输出

1 2
6 7 8 9 10
11 12 13 14
3 4

样例说明

  1) 购2张票,得到座位1、2。
  2) 购5张票,得到座位6至10。
  3) 购4张票,得到座位11至14。
  4) 购2张票,得到座位3、4。

评测用例规模与约定

  对于所有评测用例,1 ≤ n ≤ 100,所有购票数量之和不超过100。

#include <iostream>
#include <cstring>
using namespace std;
int tt[105];
int main()
{
    int n;
    while(cin>>n)
    {
        int z;
        memset(tt,0,sizeof(tt));
        for(int i=0; i<n; i++)
        {
            cin>>z;
            int c,begin1;
            int f=0;
            for(int i=1; i<=96; i+=5)
            {
                begin1=i;
                c=0;
                for(int j=i; j<i+5; j++)
                {
                    if(tt[j]==0)
                        c++;
                    if(c==1)
                    {
                        begin1=j;
                    }
                    if(c>=z)
                        break;
                }
                if(c>=z)
                {
                    f=1;
                    break;
                }
            }
            if(f)
            {
                for(int i=begin1; i<begin1+z; i++)
                {
                    tt[i]=1;
                    cout<<i<<" ";
                }
                cout<<endl;
            }
            else
            {
                for(int i=1; i<=100; i++)
                {
                    if(tt[i]==0)
                    {
                        tt[i]=1;
                        cout<<i<<" ";
                    }
                }
                cout<<endl;
            }
        }
    }
}
/*
21
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 4 2
*/
试题编号:201612-2
试题名称:工资计算
时间限制:1.0s
内存限制:256.0MB
问题描述:

问题描述

  小明的公司每个月给小明发工资,而小明拿到的工资为交完个人所得税之后的工资。假设他一个月的税前工资(扣除五险一金后、未扣税前的工资)为S元,则他应交的个人所得税按如下公式计算:
  1) 个人所得税起征点为3500元,若S不超过3500,则不交税,3500元以上的部分才计算个人所得税,令A=S-3500元;
  2) A中不超过1500元的部分,税率3%;
  3) A中超过1500元未超过4500元的部分,税率10%;
  4) A中超过4500元未超过9000元的部分,税率20%;
  5) A中超过9000元未超过35000元的部分,税率25%;
  6) A中超过35000元未超过55000元的部分,税率30%;
  7) A中超过55000元未超过80000元的部分,税率35%;
  8) A中超过80000元的部分,税率45%;
  例如,如果小明的税前工资为10000元,则A=10000-3500=6500元,其中不超过1500元部分应缴税1500×3%=45元,超过1500元不超过4500元部分应缴税(4500-1500)×10%=300元,超过4500元部分应缴税(6500-4500)×20%=400元。总共缴税745元,税后所得为9255元。
  已知小明这个月税后所得为T元,请问他的税前工资S是多少元。

输入格式

  输入的第一行包含一个整数T,表示小明的税后所得。所有评测数据保证小明的税前工资为一个整百的数。

输出格式

  输出一个整数S,表示小明的税前工资。

样例输入

9255

样例输出

10000

评测用例规模与约定

  对于所有评测用例,1 ≤ T ≤ 100000。

找范围找到吐血

#include <iostream>
#include <cstring>
using namespace std;
int cc[10]={0,1455,4155,7755,27255,41255,57505};
int main()
{
    int n;
    while(cin>>n)
    {
        int c=n;
        c-=3500;
        int i=0;
      while(c>=cc[i]&&i<=6)
      {
          i++;
      }
      if(i==0)
      {
          cout<<n<<endl;
      }
      else if(i==1)
      {
          cout<<3500+(n-3500)/0.97<<endl;
      }
        else if(i==2)
      {
          cout<<3500+1500+(n+45-(3500+1500))/0.9<<endl;
      }
        else if(i==3)
      {
          cout<<3500+4500+(n+345-(3500+4500))/0.8<<endl;
      }
        else if(i==4)
      {
          cout<<3500+9000+(n+1245-(3500+9000))/0.75<<endl;
      }
        else if(i==5)
      {
          cout<<3500+35000+(n+7745-(3500+35000))/0.7<<endl;
      }
        else if(i==6)
      {
          cout<<3500+55000+(n+13745-(3500+55000))/0.65<<endl;
      }
        else if(i==7)
      {
          cout<<3500+80000+(n+22495-(3500+80000))/0.55<<endl;
      }
    }
}


试题编号:201703-2
试题名称:学生排队
时间限制:1.0s
内存限制:256.0MB
问题描述:

问题描述

  体育老师小明要将自己班上的学生按顺序排队。他首先让学生按学号从小到大的顺序排成一排,学号小的排在前面,然后进行多次调整。一次调整小明可能让一位同学出队,向前或者向后移动一段距离后再插入队列。
  例如,下面给出了一组移动的例子,例子中学生的人数为8人。
  0)初始队列中学生的学号依次为1, 2, 3, 4, 5, 6, 7, 8;
  1)第一次调整,命令为“3号同学向后移动2”,表示3号同学出队,向后移动2名同学的距离,再插入到队列中,新队列中学生的学号依次为1, 2, 4, 5, 3, 6, 7, 8;
  2)第二次调整,命令为“8号同学向前移动3”,表示8号同学出队,向前移动3名同学的距离,再插入到队列中,新队列中学生的学号依次为1, 2, 4, 5, 8, 3, 6, 7;
  3)第三次调整,命令为“3号同学向前移动2”,表示3号同学出队,向前移动2名同学的距离,再插入到队列中,新队列中学生的学号依次为1, 2, 4, 3, 5, 8, 6, 7。
  小明记录了所有调整的过程,请问,最终从前向后所有学生的学号依次是多少?
  请特别注意,上述移动过程中所涉及的号码指的是学号,而不是在队伍中的位置。在向后移动时,移动的距离不超过对应同学后面的人数,如果向后移动的距离正好等于对应同学后面的人数则该同学会移动到队列的最后面。在向前移动时,移动的距离不超过对应同学前面的人数,如果向前移动的距离正好等于对应同学前面的人数则该同学会移动到队列的最前面。

输入格式

  输入的第一行包含一个整数n,表示学生的数量,学生的学号由1到n编号。
  第二行包含一个整数m,表示调整的次数。
  接下来m行,每行两个整数p, q,如果q为正,表示学号为p的同学向后移动q,如果q为负,表示学号为p的同学向前移动-q。

输出格式

  输出一行,包含n个整数,相邻两个整数之间由一个空格分隔,表示最终从前向后所有学生的学号。

样例输入

8
3
3 2
8 -3
3 -2

样例输出

1 2 4 3 5 8 6 7

评测用例规模与约定

  对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ m ≤ 1000,所有移动均合法。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef struct node
{
    int x,id;
} xx;
int n,m;
xx tt[1005];
bool cmp(node a,node b)
{
    return a.id<b.id;
}
int findt(int x)
{
    for(int i=1; i<=n; i++)
    {
        if(tt[i].x==x)
            return i;
    }
}
int main()
{

    while(cin>>n>>m)
    {
        for(int i=1; i<=n; i++)
        {
            tt[i].x=tt[i].id=i;
        }
        for(int i=0; i<m; i++)
        {
            int x,y;
            cin>>x>>y;
            int zz=findt(x);
            if(y>0)
            {
                for(int  j=tt[zz].id+1; j<=tt[zz].id+y; j++)
                {
                    tt[j].id--;
                }
                tt[zz].id+=(y);
            }
            else
            {
                for(int j=tt[zz].id+y; j<=tt[zz].id-1; j++)
                {
                    tt[j].id++;
                }
                tt[zz].id+=(y);
            }
            sort(tt+1,tt+n+1,cmp);
        }
        sort(tt+1,tt+n+1,cmp);
        for(int i=1; i<=n; i++)
        {
            cout<<tt[i].x<<" ";
        }
        cout<<endl;
    }
}


试题编号:201712-2
试题名称:游戏
时间限制:1.0s
内存限制:256.0MB
问题描述:

问题描述

  有n个小朋友围成一圈玩游戏,小朋友从1至n编号,2号小朋友坐在1号小朋友的顺时针方向,3号小朋友坐在2号小朋友的顺时针方向,……,1号小朋友坐在n号小朋友的顺时针方向。
  游戏开始,从1号小朋友开始顺时针报数,接下来每个小朋友的报数是上一个小朋友报的数加1。若一个小朋友报的数为k的倍数或其末位数(即数的个位)为k,则该小朋友被淘汰出局,不再参加以后的报数。当游戏中只剩下一个小朋友时,该小朋友获胜。
  例如,当n=5, k=2时:
  1号小朋友报数1;
  2号小朋友报数2淘汰;
  3号小朋友报数3;
  4号小朋友报数4淘汰;
  5号小朋友报数5;
  1号小朋友报数6淘汰;
  3号小朋友报数7;
  5号小朋友报数8淘汰;
  3号小朋友获胜。

  给定nk,请问最后获胜的小朋友编号为多少?

输入格式

  输入一行,包括两个整数nk,意义如题目所述。

输出格式

  输出一行,包含一个整数,表示获胜的小朋友编号。

样例输入

5 2

样例输出

3

样例输入

7 3

样例输出

4

数据规模和约定

  对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ k ≤ 9。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
int main()
{
    int n,m;

    while(cin>>n>>m)
    {
        queue<int > xx;
        for(int i=1; i<=n; i++)
        {
            xx.push(i);
        }
        int cnt=1;
        while(xx.size()!=1)
        {
            int x=xx.front();
            if(cnt%m!=0&&cnt%10!=m)
            {
                xx.push(x);
                xx.pop();
            }
            else
            {
                xx.pop();
            }
            cnt++;
        }
        cout<<xx.front()<<endl;
    }
}



试题编号:201803-2
试题名称:碰撞的小球
时间限制:1.0s
内存限制:256.0MB
问题描述:

问题描述

  数轴上有一条长度为L(L为偶数)的线段,左端点在原点,右端点在坐标L处。有n个不计体积的小球在线段上,开始时所有的小球都处在偶数坐标上,速度方向向右,速度大小为1单位长度每秒。
  当小球到达线段的端点(左端点或右端点)的时候,会立即向相反的方向移动,速度大小仍然为原来大小。
  当两个小球撞到一起的时候,两个小球会分别向与自己原来移动的方向相反的方向,以原来的速度大小继续移动。
  现在,告诉你线段的长度L,小球数量n,以及n个小球的初始位置,请你计算t秒之后,各个小球的位置。

提示

  因为所有小球的初始位置都为偶数,而且线段的长度为偶数,可以证明,不会有三个小球同时相撞,小球到达线段端点以及小球之间的碰撞时刻均为整数。
  同时也可以证明两个小球发生碰撞的位置一定是整数(但不一定是偶数)。

输入格式

  输入的第一行包含三个整数n, L, t,用空格分隔,分别表示小球的个数、线段长度和你需要计算t秒之后小球的位置。
  第二行包含n个整数a1, a2, …, an,用空格分隔,表示初始时刻n个小球的位置。

输出格式

  输出一行包含n个整数,用空格分隔,第i个整数代表初始时刻位于ai的小球,在t秒之后的位置。

样例输入

3 10 5
4 6 8

样例输出

7 9 9

样例说明

  初始时,三个小球的位置分别为4, 6, 8。

  一秒后,三个小球的位置分别为5, 7, 9。

  两秒后,第三个小球碰到墙壁,速度反向,三个小球位置分别为6, 8, 10。

  三秒后,第二个小球与第三个小球在位置9发生碰撞,速度反向(注意碰撞位置不一定为偶数),三个小球位置分别为7, 9, 9。

  四秒后,第一个小球与第二个小球在位置8发生碰撞,速度反向,第三个小球碰到墙壁,速度反向,三个小球位置分别为8, 8, 10。

  五秒后,三个小球的位置分别为7, 9, 9。

样例输入

10 22 30
14 12 16 6 10 2 8 20 18 4

样例输出

6 6 8 2 4 0 4 12 10 2

数据规模和约定

  对于所有评测用例,1 ≤ n ≤ 100,1 ≤ t ≤ 100,2 ≤ L ≤ 1000,0 < ai < L。L为偶数。
  保证所有小球的初始位置互不相同且均为偶数。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef struct node
{
    int index,v;
} ball;
ball b[105];
int main()
{
    int n,l,t;
    while(cin>>n>>l>>t)
    {
        for(int i=0; i<n; i++)
        {
            cin>>b[i].index;
            b[i].v=1;
        }
        for(int i=0; i<t; i++)
        {
            for(int j=0; j<n; j++)
            {
                b[j].index+=b[j].v;
                if(b[j].index==l ||b[j].index==0)
                    b[j].v*=-1;
            }
            for(int x=0; x<n-1; x++)
            {
                for(int j=x+1; j<n; j++)
                {
                    if(b[x].index==b[j].index)
                    {
                        b[x].v*=-1;
                        b[j].v*=-1;
                    }
                }
            }
            /* for(int g=0; g<n; g++)
             cout<<b[g].index<<" ";
            cout<<endl;*/

        }
        for(int i=0; i<n; i++)
            cout<<b[i].index<<" ";
        cout<<endl;
    }
}



 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值