第三届CCF软件能力认证
1.门禁系统
问题描述
涛涛最近要负责图书馆的管理工作,需要记录下每天读者的到访情况。每位读者有一个编号,每条记录用读者的编号来表示。给出读者的来访记录,请问每一条记录中的读者是第几次出现。
输入格式
输入的第一行包含一个整数n,表示涛涛的记录条数。
第二行包含n个整数,依次表示涛涛的记录中每位读者的编号。
输出格式
输出一行,包含n个整数,由空格分隔,依次表示每条记录中的读者编号是第几次出现。
样例输入
5
1 2 1 1 3
样例输出
1 1 2 3 1
评测用例规模与约定
1≤n≤1,000,读者的编号为不超过n的正整数。
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <cmath> 6 # define LL long long 7 using namespace std ; 8 9 int a[1010] ; 10 11 int main () 12 { 13 //freopen("in.txt","r",stdin) ; 14 int n ; 15 scanf("%d" , &n) ; 16 int i , x ; 17 for (i = 1 ; i <= n-1 ; i++) 18 { 19 scanf("%d" , &x) ; 20 a[x]++ ; 21 printf("%d " , a[x]) ; 22 } 23 scanf("%d" , &x) ; 24 a[x]++ ; 25 printf("%d\n" , a[x]) ; 26 27 return 0 ; 28 }
2.蛇形图
问题描述
在图像编码的算法中,需要将一个给定的方形矩阵进行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 <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <cmath> 6 # define LL long long 7 using namespace std ; 8 9 int map[500][500] ; 10 11 int main () 12 { 13 //freopen("in.txt","r",stdin) ; 14 int n ; 15 scanf("%d" , &n) ; 16 int i , j ; 17 for (i = 1 ; i <= n ; i++) 18 for (j = 1 ; j <= n ; j++) 19 scanf("%d" , &map[i][j]) ; 20 i = j = 1 ; 21 int tag1 = 1 ; 22 int tag2 = 0 ; 23 24 while(i != n || j != n) 25 { 26 while (tag1) 27 { 28 if (i != 1 && j != n) 29 { 30 printf("%d " , map[i][j]) ; 31 i-- ; 32 j++ ; 33 } 34 else if (j == n) 35 { 36 printf("%d " , map[i][j]) ; 37 i++ ; 38 tag1 = 0 ; 39 tag2 = 1 ; 40 } 41 else if (i == 1) 42 { 43 printf("%d " , map[i][j]) ; 44 j++ ; 45 tag1 = 0 ; 46 tag2 = 1 ; 47 } 48 } 49 while(tag2) 50 { 51 if (i != n && j != 1) 52 { 53 printf("%d " , map[i][j]) ; 54 i++ ; 55 j-- ; 56 } 57 else if (i == n) 58 { 59 printf("%d " , map[i][j]) ; 60 j++ ; 61 tag2 = 0 ; 62 tag1 = 1 ; 63 } 64 else if (j == 1) 65 { 66 printf("%d " , map[i][j]) ; 67 i++ ; 68 tag2 = 0 ; 69 tag1 = 1 ; 70 } 71 } 72 } 73 74 printf("%d\n" , map[i][j]) ; 75 76 return 0 ; 77 }
3.集合竞价
问题描述
某股票交易所请你编写一个程序,根据开盘前客户提交的订单来确定某特定股票的开盘价和开盘成交量。
该程序的输入由很多行构成,每一行为一条记录,记录可能有以下几种:
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。
4.
最优灌溉
问题描述
雷雷承包了很多片麦田,为了灌溉这些麦田,雷雷在第一个麦田挖了一口很深的水井,所有的麦田都从这口井来引水灌溉。
为了灌溉,雷雷需要建立一些水渠,以连接水井和麦田,雷雷也可以利用部分麦田作为“中转站”,利用水渠连接不同的麦田,这样只要一片麦田能被灌溉,则与其连接的麦田也能被灌溉。
现在雷雷知道哪些麦田之间可以建设水渠和建设每个水渠所需要的费用(注意不是所有麦田之间都可以建立水渠)。请问灌溉所有麦田最少需要多少费用来修建水渠。
输入格式
输入的第一行包含两个正整数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。
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <cmath> 6 # define LL long long 7 using namespace std ; 8 9 int n ; 10 const int MAXN=1010; 11 const int MAXM=200010; 12 int F[MAXN]; 13 struct Edge 14 { 15 int u,v,w; 16 }edge[MAXM]; 17 18 int tol; 19 void addedge(int u,int v,int w) 20 { 21 22 edge[tol].u=u; 23 edge[tol].v=v; 24 edge[tol++].w=w; 25 } 26 bool cmp(Edge a,Edge b) 27 { 28 return a.w<b.w; 29 } 30 int find(int x) 31 { 32 if(F[x]==-1)return x; 33 else return F[x]=find(F[x]); 34 } 35 int Kruskal() 36 { 37 memset(F,-1,sizeof(F)); 38 sort(edge,edge+tol,cmp); 39 int cnt=0; 40 int ans=0; 41 for(int i=0;i<tol;i++) 42 { 43 int u=edge[i].u; 44 int v=edge[i].v; 45 int w=edge[i].w; 46 int t1=find(u); 47 int t2=find(v); 48 if(t1!=t2) 49 { 50 ans+=w; 51 F[t1]=t2; 52 cnt++; 53 } 54 if(cnt==n-1)break; 55 } 56 if(cnt<n-1)return -1; 57 else return ans; 58 } 59 60 int main() 61 { 62 //freopen("in.txt","r",stdin) ; 63 int m ; 64 scanf("%d %d" , &n , &m) ; 65 int i ; 66 int u , v , w ; 67 tol = 0 ; 68 while(m--) 69 { 70 scanf("%d %d %d" , &u , &v , &w) ; 71 addedge(u , v , w) ; 72 addedge(v , u , w) ; 73 } 74 int k = Kruskal() ; 75 printf("%d\n" , k) ; 76 77 return 0 ; 78 }
5.
货物调度
问题描述
某公司要处理一个周期性的物流问题。
有n个城市,第i个城市在每周的第j(1≤j≤7) 天会生产aij吨某种货物,同时需要消耗bij吨该种货物。已知每周的产量等于消耗量(即aij之和等于bij之和)。
城市之间有m条道路,第k条道路连接了城市sk和tk。一条道路上运输1吨货物有一个固定的成本ck。道路都可以双向使用。每天运输的货物量没有限制。城市之间的距离并不远,货物可以从任意一个城市运输到任意另一个城市并且在当天到达。
货物如果在当天没有被消耗掉,就需要存放在仓库里过夜。第i个城市的仓库容量为vi,存放1 吨货物过一夜所需的成本是wi。
请你计算该公司如果每周循环性地按照一个固定的流程调度货物的话,该公司在最优方案下每周需要为货物的运输和存储消耗多少成本。
输入格式
输入的第一行有两个正整数n和m,即城市的个数和道路的条数。
接下来有n行,每行包含16个整数,用以描述第i个城市的相关数据。其中第i行包含的数为ai1, ai2, ai3, ai4, ai5, ai6, ai7, bi1, bi2, bi3, bi4, bi5, bi6, bi7, vi, wi。
接下来有m行,每行包含3个整数,用以描述一条道路的相关数据。其中第k行包含的数为sk, tk和ck。
输入数据中城市的编号均为1到n之间。输入数据的每行的行首行尾均保证没有空格,两个数之间恰好被一个空格隔开。
输出格式
你只需要输出一个数,即最优方案下每周的支出。
样例输入
3 3
0 0 0 0 5 0 0 0 0 0 0 0 0 0 2 4
0 0 0 0 0 0 0 2 0 0 0 0 0 0 2 1
0 0 0 0 0 0 0 0 0 3 0 0 0 0 2 5
1 2 1
1 3 5
2 3 1
样例输出
67
样例说明
城市1 每周五生产5 吨货物,把其中2 吨运到存储费用低廉的城市2 存储,把1 吨运到城市3 存储,剩下的2 吨留在城市1。
在次周一的时候城市2 会消耗掉存放在那里的2 吨货物。为了节约存储成本,将囤放在城市1 的货物运到城市2 存放。周三再将所有货物运到城市3 以满足该城市的需求。
在此方案下,每周的运输成本为8,每周的存储成本为59,因此每周的总支出为67。
评测用例规模与约定
对于100%的数据,1≤n≤100,1≤m≤500,0≤aij,bij,vi≤100,1≤wi,ck≤100。