CSP-201412

问题描述

试题编号: 201412-1
试题名称: 门禁系统
时间限制: 1.0s
内存限制: 256.0MB
问题描述:
问题描述
  涛涛最近要负责图书馆的管理工作,需要记录下每天读者的到访情况。每位读者有一个编号,每条记录用读者的编号来表示。给出读者的来访记录,请问每一条记录中的读者是第几次出现。
输入格式
  输入的第一行包含一个整数n,表示涛涛的记录条数。
  第二行包含n个整数,依次表示涛涛的记录中每位读者的编号。
输出格式
  输出一行,包含n个整数,由空格分隔,依次表示每条记录中的读者编号是第几次出现。
样例输入
5
1 2 1 1 3
样例输出
1 1 2 3 1
评测用例规模与约定
  1≤n≤1,000,读者的编号为不超过n的正整数。

模拟即可。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int n,a,tot[1010]={0};
 5     cin>>n;
 6     for(int i=1;i<=n;++i){
 7         cin>>a;
 8         cout<<++tot[a]<<(i==n?'\n':' ');
 9     }
10     return 0;
11 }
View Code

 

 问题描述

试题编号: 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的正整数。

 观察可发现只有四个方向作为移动方向,模拟下由上一个方向加上当前位置推断出下一个方向得过程即可。细节题。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int fx[4][2]={
 4     0,1,//
 5     1,0,//
 6     1,-1,//左下
 7     -1,1//右上
 8 };
 9 int n,num[505][505];
10 int main(){
11     scanf("%d",&n);
12     for(int i=1;i<=n;++i){
13         for(int j=1;j<=n;++j){
14             scanf("%d",&num[i][j]);
15         }
16     }
17     int x=1,y=1,q=3;
18     while(1){
19         if(x==n&&y==n){
20             cout<<num[n][n]<<endl;
21             break;
22         }
23         else{
24            cout<<num[x][y]<<' ';
25            switch(q){
26            case 0:
27                if(x==1)q=2;
28                else if(x==n) q=3;
29                break;
30            case 1:
31                if(y==1)q=3;
32                else if(y==n) q=2;
33                break;
34            case 2:
35                if(x==n)q=0;
36                else if(y==1) q=1;
37                break;
38            case 3:
39                if(y==n)q=1;
40                else if(x==1)q=0;
41 
42                break;
43            }
44            x=x+fx[q][0];
45            y=y+fx[q][1];
46         }
47     }
48     return 0;
49 }
View Code

 

 

问题描述

试题编号: 201412-3
试题名称: 集合竞价
时间限制: 1.0s
内存限制: 256.0MB
问题描述:
问题描述
  某股票交易所请你编写一个程序,根据开盘前客户提交的订单来确定某特定股票的开盘价和开盘成交量。
  该程序的输入由很多行构成,每一行为一条记录,记录可能有以下几种:
  1. buy p s 表示一个购买股票的买单,每手出价为p,购买股数为s。
  2. sell p s 表示一个出售股票的卖单,每手出价为p,出售股数为s。
  3. cancel i表示撤销第i行的记录。
  如果开盘价为p0,则系统可以将所有出价至少为p0的买单和所有出价至多为p0的卖单进行匹配。因此,此时的开盘成交量为出价至少为p0的买单的总股数和所有出价至多为p0的卖单的总股数之间的较小值。
  你的程序需要确定一个开盘价,使得开盘成交量尽可能地大。如果有多个符合条件的开盘价,你的程序应当输出最高的那一个。
输入格式
  输入数据有任意多行,每一行是一条记录。保证输入合法。股数为不超过108的正整数,出价为精确到恰好小数点后两位的正实数,且不超过10000.00。
输出格式
  你需要输出一行,包含两个数,以一个空格分隔。第一个数是开盘价,第二个是此开盘价下的成交量。开盘价需要精确到小数点后恰好两位。
样例输入
buy 9.25 100
buy 8.88 175
sell 9.00 1000
buy 9.00 400
sell 8.92 400
cancel 1
buy 100.00 50
样例输出
9.00 450
评测用例规模与约定
  对于100%的数据,输入的行数不超过5000。

第三题一般是个大模拟。

观察后发现这个开盘价一定是所有合法buy中得某一个价格,因此对buy中每个价格都尝试一下即可,用二分会加速尝试速度,但测试用例没那么强,暴力查找完全足够了。

注意成交量是会超过int表示范围得,因此设计成交量的变量均使用long long比较安全。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define pfi pair<float,int>
 4 bool cancel[5050];
 5 float buy0[5050],sell0[5050];
 6 int buy1[5050],sell1[5050];
 7 int type[5050];
 8 long long  sum1[5050],sum2[5050];
 9 vector<pfi> buy,sell;
10 int main(){
11     string str;
12     float x;
13     int y,n=0;
14     while(cin>>str){
15            // if(str=="END")break;
16         n++;
17         if(str=="buy"){
18             type[n]=0;
19             cin>>buy0[n]>>buy1[n];
20         }else if(str=="sell"){
21             type[n]=1;
22             cin>>sell0[n]>>sell1[n];
23         }
24         else if(str=="cancel"){
25             type[n]=2;
26             cin>>y;
27             cancel[y]^=1;
28         }
29     }
30     pfi p;
31     for(int i=1;i<=n;++i){
32         if(type[i]==2||cancel[i]==1)continue;
33         if(type[i]==0){
34             p.first=buy0[i];
35             p.second=buy1[i];
36             buy.push_back(p);
37         }else{
38             p.first=sell0[i];
39             p.second=sell1[i];
40             sell.push_back(p);
41         }
42     }
43     sort(buy.begin(),buy.end());
44     sort(sell.begin(),sell.end());
45     for(int i=1;i<=buy.size();++i){
46         sum1[i]=sum1[i-1]+buy[i-1].second;
47     }
48     for(int i=1;i<=sell.size();++i){
49         sum2[i]=sum2[i-1]+sell[i-1].second;
50     }
51     float ans0=0;
52     long long  ans1=0;
53     for(int i=0;i<buy.size();++i){
54         long long  n1=sum1[buy.size()]-sum1[i];
55         long long n2=0;
56         for(int j=0;j<sell.size() && sell[j].first<=buy[i].first;++j){
57             n2+=sell[j].second;
58         }
59         if(ans1<min(n1,n2)){
60             ans1=min(n1,n2);
61             ans0=buy[i].first;
62         }
63         else if(ans1==min(n1,n2)){
64             ans0=buy[i].first;
65         }
66     }
67     printf("%.2f %lld\n",ans0,ans1);
68     return 0;
69 }
View Code

 

 

问题描述

试题编号: 201412-4
试题名称: 最优灌溉
时间限制: 1.0s
内存限制: 256.0MB
问题描述:
问题描述
  雷雷承包了很多片麦田,为了灌溉这些麦田,雷雷在第一个麦田挖了一口很深的水井,所有的麦田都从这口井来引水灌溉。
  为了灌溉,雷雷需要建立一些水渠,以连接水井和麦田,雷雷也可以利用部分麦田作为“中转站”,利用水渠连接不同的麦田,这样只要一片麦田能被灌溉,则与其连接的麦田也能被灌溉。
  现在雷雷知道哪些麦田之间可以建设水渠和建设每个水渠所需要的费用(注意不是所有麦田之间都可以建立水渠)。请问灌溉所有麦田最少需要多少费用来修建水渠。
输入格式
  输入的第一行包含两个正整数n, m,分别表示麦田的片数和雷雷可以建立的水渠的数量。麦田使用1, 2, 3, ……依次标号。
  接下来m行,每行包含三个整数ai, bi, ci,表示第ai片麦田与第bi片麦田之间可以建立一条水渠,所需要的费用为ci
输出格式
  输出一行,包含一个整数,表示灌溉所有麦田所需要的最小费用。
样例输入
4 4
1 2 1
2 3 4
2 4 2
3 4 3
样例输出
6
样例说明
  建立以下三条水渠:麦田1与麦田2、麦田2与麦田4、麦田4与麦田3。
评测用例规模与约定
  前20%的评测用例满足:n≤5。
  前40%的评测用例满足:n≤20。
  前60%的评测用例满足:n≤100。
  所有评测用例都满足:1≤n≤1000,1≤m≤100,000,1≤ci≤10,000。

 

MST模板题目,没啥好说的。这里明显适用于Prim算法,但是Kruskal也完全可以AC。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define pfi pair<float,int>
 4 int f[1010],n,m;
 5 int getf(int u){
 6     return u==f[u]?f[u]:f[u]=getf(f[u]);
 7 }
 8 struct Edge{
 9     int u,v,w;
10     bool operator<(const Edge &chr)const{
11         return w<chr.w;
12     }
13 }e[100010];
14 int main(){
15     int u,v,w;
16     cin>>n>>m;
17     for(int i=1;i<=n;++i)f[i]=i;
18     for(int i=0;i<m;++i){
19         cin>>e[i].u>>e[i].v>>e[i].w;
20     }
21     sort(e,e+m);
22     int ans=0;
23     for(int i=0;i<m;++i){
24         u=e[i].u,v=e[i].v,w=e[i].w;
25         int fu=getf(f[u]);
26         int fv=getf(f[v]);
27         if(fv==fu)continue;
28         f[fv]=fu;
29         ans+=w;
30     }
31     cout<<ans<<endl;
32     return 0;
33 }
View Code

 

-

posted @ 2020-01-04 10:04  *zzq  阅读(199)  评论(0编辑  收藏  举报