安徽大学第九届大学生程序设计竞赛 网络预选赛
来源:互联网 发布:java多线程编程实战 编辑:程序博客网 时间:2024/04/29 16:44
Total Submission: 250 Submission Accepted: 76
对于每组测试数据,第一行两个整数,n和m,(1<=n,m<=50)
接下来n行,每一行有m个数字(中间不分隔),表示这个学生每门课的成绩,其中成绩为1-9的整数。
23 32232321123 5917281182811111
23
上代码:
#include<iostream>#include<cstring>#include<algorithm>#include<string>#include<cstdio>using namespace std;int success[100];struct stu{ int num; int core;};bool cmp(stu a,stu b){ return a.core >b.core;}int main(){ int t,m,n,i,j; stu students[100]; char a[100][100]; cin>>t; while(t--){ int ans=0; memset(success,0,sizeof(success)); cin>>n>>m; for(i=0;i<n;i++){ getchar(); scanf("%s",a[i]); } for(i=0;i<m;i++){ for(j=0;j<n;j++){ students[j].core=(int)a[j][i]-'0'; students[j].num=j; } sort(students,students+n,cmp);//排列 for(j=0;j<n;j++){ success[students[j].num]=1; if(students[j+1].core!=students[j].core) break; }//并列的全都标记 } for(i=0;i<n;i++){ if(success[i]==1) ans++; } cout<<ans<<endl; } }
PS(转):
题解
取出每个人每门课的成绩,排序后找出最大的几个,然后将他们的编号插入到 set 里
最后计算 set 的元素数量即可
#include <iostream>#include <cstring>#include <set>#include <algorithm>using namespace std;const int maxn = 55;char score[maxn][maxn];set<int> ans;struct Node{ int n; int w; Node(int a=-1,int b=-1):n(a),w(b){} bool operator < (const Node &rhs)const{ return w > rhs.w; }}node[maxn];int main(){ #ifdef debug freopen("in.txt", "r", stdin); int START = clock(); #endif cin.tie(0); cin.sync_with_stdio(false); int T; cin >> T; while(T--){ ans.clear(); int n,m; cin >> n >> m; for(int i=0;i<n;i++) cin >> score[i]; for(int i=0;i<m;i++){ for(int j=0;j<n;j++) node[j] = Node(j,score[j][i]); sort(node,node+n); int t = node[0].w; for(int j=0;j<n;j++){ if(t == node[j].w) ans.insert(node[j].n); else break; } } cout << ans.size() << endl; } #ifdef debug printf("Time:%.3fs.\n", double(clock() - START) / CLOCKS_PER_SEC); #endif return 0;}
Total Submission: 323 Submission Accepted: 74
如,9876经过一次变换成为9+8+7+6=30,经过第二次变换成为3+0=3,结束。
那么9876就经过了两次迭代变换。如今给一个正整数,问需要迭代变换多少次后会停止。
对于每组测试数据,只有一行,表示一个正整数,正整数最多有100000位。
321099999999
012
#include<iostream>#include<cstring>#include<algorithm>#include<string>#include<cstdio>using namespace std;int main(){ char a[100010]; int t,n,flag,ans; long long int sum; cin>>t; while(t--){ sum=0; ans=0; flag=0; scanf("%s",a); sum+=(int)a[0]-'0'; for(int i=1;a[i]>='0' && a[i]<='9';i++){ sum+=(int)a[i]-'0'; if(flag==0){ flag=1; ans++; } } while(sum>=10){ cout<<ans<<" "<<sum<<endl; n=sum; sum=0; while(n>0){ sum+=n%10; n/=10; } ans++; } cout<<ans<<" "<<sum<<endl; cout<<ans<<endl; } return 0;}
PS(转):
#include <iostream>#include <cstring>using namespace std; const int maxn = 100005;char s[100005];int main(){ #ifdef debug freopen("in.txt", "r", stdin); int START = clock(); #endif cin.tie(0); cin.sync_with_stdio(false); int T; scanf("%d",&T); while(T--){ int ans = 0; scanf("%s",s); int size = strlen(s); int n = 0; bool flag = false; for(int i = 0;i < size;i++){ n += s[i]-'0'; if(flag) ans=1; if(!flag && s[i] - '0' > 0) flag = true; } while(n>=10){ ans++; int t = 0; while(n){ t += n%10; n /= 10; } n = t; } printf("%d\n",ans); } #ifdef debug printf("Time:%.3fs.\n", double(clock() - START) / CLOCKS_PER_SEC); #endif return 0;}
Total Submission: 452 Submission Accepted: 30
如1,2,3和3,1,2都是1-3的排列,但是1,3,3不是1-3的排列。
如今,给n个数,问最少修改几个数,可以使得序列成为1-n的一个排列。
对于每一组测试数据,第一行为一个整数n,(1 <= n <= 500)
第二行有n个整数a1,a2,……an,空格分隔,(ai为任意的32位有符号正整数)。
保证多组数据中的n的和不超过100000。
251 3 2 4 561 1 1 1 1 1
05
上代码:
/*怎么看都觉得坑,按下面解题者的意思来说就是,测试数据量和题目给的不一样,数组得开大一点,难怪我的总是runtime error,一个同学数组开到100000+10,通过了*/
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
using
namespace
std;
int
vis[510];//这里如果开到100000+10,应该就通过了
int
main(){
int
t,n,ans;
long
long
int
x;
cin>>t;
while
(t--){
ans=0;
memset
(vis,0,
sizeof
(vis));
cin>>n;
for
(
int
i=0;i<n;i++){
cin>>x;
if
(x<=n && x>0) //显然,题目如果给的n值超过500,runtime error就能解释了
vis[x]=1;
}
for
(
int
i=1;i<=n;i++){
if
(!vis[i])
ans++;
}
cout<<ans<<endl;
}
return
0;
}
ps(转):
题解
思路应该很容易,不过数据比较坑
用一个数组来记录 1-n
的数字哪个已经读入过了
没有读入的就是要交换的
这道题数据量和题目给的不一样
开大一点能解决
另外可以使用 set 来保存
只要是 1-n
的数字,直接扔到 set 里
最后 n-s.size()
即可
数字存在负数,因此读入的判断两侧都要判断
#include <cstdio>#include <iostream>#include <cstring>#include <set>using namespace std;int main(){ #ifdef debug freopen("in.txt", "r", stdin); int START = clock(); #endif cin.tie(0); cin.sync_with_stdio(false); int T; scanf("%d",&T); while(T--){ set<int> s; s.clear(); int n; scanf("%d",&n); for(int i=0;i<n;i++){ int t; scanf("%d",&t); if(t <= n && t >= 1) s.insert(t); } printf("%d\n",n-s.size()); } #ifdef debug printf("Time:%.3fs.\n", double(clock() - START) / CLOCKS_PER_SEC); #endif return 0;}
Total Submission: 286 Submission Accepted: 56
现在可以买的一共三种道具,分别是房子(每一个价值1234567个游戏币),车子(每一个价值123456个游戏币),电脑(每一个价值1234个游戏币)。
现在她想知道,通过买这三种道具是否可以把n个游戏币全部花光。
对于每一组测试数据,一个整数n(1<=n<=1000000000),代表现在的游戏币。
2135925717851817
YESNO
/*这题我没写出来,因为金额太大,本想用背包的,结果开不了那么大的数组~~~~~~,看看人家的吧*/
ps(转):
题解
由于最大的值非常大,如果直接 dfs 会非常慢
而且打表的文件会非常大
而看 1234567
和 1000000000
其实差别不是很大
除一下发现最多也就能买 800
多套房子
而即使全部买成汽车也就能买 8000
多辆
乘起来的数据量只有 10e6
完全是可以遍历的
也就是说,只需要枚举房子和车的数量,然后判断剩下的钱能不能整除电脑
这样做不超时的原因是房子和车的价格都非常大,可以将许多数据“跨越”掉
如果这数都很小的话,就没有办法了
#include<bits/stdc++.h>using namespace std;int main() {int T;cin >> T;while(T--) {int n;cin >> n;int flag = 0;//int a = n/1234567;//int b = n/123456;for(int i = 0 ; i <= n/1234567 ; i ++) {for(int j = 0 ; j <= n/123456 ; j ++) {if(n >= i*1234567 + j*123456){int cur = n - i*1234567 - j*123456;if(cur % 1234 == 0){flag = 1;//goto tt;break;}}}if(flag)break;}//tt:if(flag)cout << "YES" << endl;elsecout << "NO" << endl;}return 0;}
Total Submission: 34 Submission Accepted: 2
为了最好地炫耀他的豪宅,西瓜准备从大门出发,经过一些楼房到达储藏室,再经过一些楼房回到自己的大门。
他要求他的路径越短越好,但是不能经过任意一条道路多于一次。请你计算这样的一条最短路径。西瓜保证这样的路径是存在的。
第2..M+1行:每行三个整数表示一条道路(起点,终点,长度)
4 51 2 12 3 13 4 11 3 22 4 2
6
/*这题我还是没写出来,这次比较有水平的一题~~~~~~,看看人家的吧*/
PS(转):
题解
本次最难的一题
要求是对于一个无向图,在每条路只走一次的情况下,从起点到终点再返回起点的最短路
看到最短路,很容易就想到 BFS ,由于每条路有一定的权值,因此需要用 Dijkstra
很显然的思路,而且能通过样例
但是如果仔细分析样例就能发现有很大的问题存在
可以很容易看出来,去的时候最短路是 3
回来的时候最短路也是 3
但是,如果单纯只是删掉第一次最短路途径的边去跑第二次最短路,有可能就会出现问题
比如,如果第一次最短路走的是 1-2-3-4
这条路,那么第二次时压根就无法返回起点
也就是说,存在有多个最短路有重边的情况
这个问题导致了单纯的搜是不行的
图论问题,不会不如试下网络流
套用网络流的概念来分析下试试
- 最短路 = 最小费用
- 每个边一次 = 流量为1
看上去好像没有问题,再深入分析下
最小费用的是 最小费用最大流
它求的是在所有最大流中费用最小的
那么我们先要限定流量
由于每个边只能走一次,边的流量显然是 1
如何体现去回两次呢?
可以在建一个源点,这个源点往外的流量为 2 ,将它连在起点或终点上,然后跑它到另一个点的最小费用最大流
由于其他点的流量都是 1 ,这个节点往外的流量是 2 ,因此只要有解,最大流必然为 2
此时建的图已经和题意的图存在一些差别了
可以看作从起点走两条完全不同的路(每条路的流量为 1 )到终点(汇点流量为 2 )
建图完毕,套用模板
匡斌的模板里点的编号是 0~n-1
因此加边的时候要把 u 和 v 分别减去 1
初始化的时候记得加上汇点
输出最小的费用即可
#include <cstdio>#include <cstring>#include <iostream>#include <cmath>#include <queue>#include <set>#include <algorithm>using namespace std;const int MAXN = 1005; const int MAXM = 10005; const int INF = 0x3f3f3f3f; struct Edge { int to,next,cap,flow,cost; }edge[MAXM]; int head[MAXN],tol; int pre[MAXN],dis[MAXN]; bool vis[MAXN]; int N;//节点总个数,节点编号从0~N-1 void init(int n){ N = n; tol = 0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int cap,int cost) { edge[tol].to = v; edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++; edge[tol].to = u; edge[tol].cap = 0; edge[tol].cost = -cost; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++; } bool spfa(int s,int t) { queue<int>q; for(int i = 0;i < N;i++) { dis[i] = INF; vis[i] = false; pre[i] = -1; } dis[s] = 0; vis[s] = true; q.push(s); while(!q.empty()){ int u = q.front(); q.pop(); vis[u] = false; for(int i = head[u]; i != -1;i = edge[i].next){ int v = edge[i].to; if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost ){ dis[v] = dis[u] + edge[i].cost; pre[v] = i; if(!vis[v]){ vis[v] = true; q.push(v); } } } } if(pre[t] == -1)return false; else return true; } //返回的是最大流,cost存的是最小费用 int minCostMaxflow(int s,int t,int &cost) { int flow = 0; cost = 0; while(spfa(s,t)){ int Min = INF; for(int i = pre[t];i != -1;i = pre[edge[i^1].to]){ if(Min > edge[i].cap - edge[i].flow) Min = edge[i].cap - edge[i].flow; } for(int i = pre[t];i != -1;i = pre[edge[i^1].to]){ edge[i].flow += Min; edge[i^1].flow -= Min; cost += edge[i].cost * Min; } flow += Min; } return flow; } int main(){ #ifdef debug freopen("in.txt", "r", stdin); int START = clock(); #endif cin.tie(0); cin.sync_with_stdio(false); int n, m; while(cin>>n>>m){ init(n+1); for(int i=0;i<m;i++){ int u,v,cost; cin >> u >> v >> cost; addedge(u-1,v-1,1,cost); addedge(v-1,u-1,1,cost); } addedge(n-1,n,2,0); int ans=0; minCostMaxflow(0,n,ans); cout << ans << endl; } #ifdef debug printf("Time:%.3fs.\n", double(clock() - START) / CLOCKS_PER_SEC); #endif return 0;}
Total Submission: 318 Submission Accepted: 116
现在你的任务是,确定火星上每年可能的最少放假的天数和最多放假的天数。
接下来n行,每行一个整数x (1<=x<=1,000,000),代表火星每年有x天。
2142
4 40 2
上代码:
#include<iostream>#include<cstring>#include<algorithm>#include<string>#include<cstdio>using namespace std;long long int n,Max,Min;int main(){ int t; cin>>t; while(t--){ Max=0; Min=0; cin>>n; Max+=n/7*2; Min+=n/7*2; if(n%7==6){ Max+=2; Min+=1; } else if(n%7>=2){ Max+=2; } else if(n%7==1){ Max+=1; } cout<<Min<<" "<<Max<<endl; } return 0;}
Total Submission: 158 Submission Accepted: 31
你最多可以获得的馅饼数量是多少呢?
接下来n行,每行两个整数a和k(1<=a<=1,000,000,000; 0<=k<=100)。
21990 11034 2
91903104
上代码:
#include<iostream>#include<cstring>#include<algorithm>#include<string>#include<cstdio>#include<vector>using namespace std;int main(){ int t,i,j,k,p,max; string a; char temp; cin>>t; while(t--){ cin>>a; getchar(); cin>>k; for(i=0;i<a.length();i++){ p=i; max=(int)a[i]; for(j=i+1;j<a.length() && j-i<=k;j++){ if((int)a[j]>max){ p=j; max=(int)a[j]; } } temp=a[p]; for(j=p;j>i;j--){ a[j]=a[j-1]; } a[i]=temp; k=k-(p-i); } cout<<a<<endl; }}
Total Submission: 478 Submission Accepted: 112
注意:1938年7月6日,小明0周岁,1938年7月7日小明1周岁,同理1939年7月6日,小明1周岁,1939年7月7日,小明2周岁。
对于每组测试数据,三个整数,逗号隔开,分别表示给定日期的年、月、日。给定的日期保证合法, 而且一定是小明出生后的日期,且小明的岁数保证在100以内。
21938 7 61938 7 7
01
上代码:
#include<iostream>#include<cstring>#include<algorithm>#include<string>#include<cstdio>using namespace std;int a[3];int main(){ int t,ans; cin>>t; while(t--){ cin>>a[0]>>a[1]>>a[2]; ans=0; if(a[0]>=1937){ ans+=a[0]-1938; if(a[1]>7 || (a[1]==7 && a[2]>=7)) ans++; } cout<<ans<<endl; } return 0;}
总结:这次网络赛做出来五题,C题如果题目数据给的没问题,应该能过六题的,剩下E题真不会,D题呢,哎,脑子转一转,其实数据给的意思可能就是让我暴力解决的。木啊!!!看别人代码也是一种是成长,尤其像我这种自己代码写得跟狗啃的一样,更应该多看看各路大神是怎么码代码的。
介绍一个不错的博客 :http://www.biyisi.cn/archives/date/2017/03
- 安徽大学第九届大学生程序设计竞赛 网络预选赛
- 安徽大学第九届大学生程序设计竞赛 网络预选赛 A
- 安徽大学第九届大学生程序设计竞赛 网络预选赛 B
- 安徽大学第九届大学生程序设计竞赛 网络预选赛 C
- 安徽大学第九届大学生程序设计竞赛 网络预选赛 D
- 安徽大学第九届大学生程序设计竞赛 网络预选赛 F
- 安徽大学第九届大学生程序设计竞赛 网络预选赛 G
- 安徽大学第九届大学生程序设计竞赛 网络预选赛 H
- 安徽大学第九届大学生程序设计竞赛热身赛
- 中南大学第九届大学生程序设计竞赛网络预选赛
- 外卖的撕‘哔’大战 Contest2074 - 中南大学第九届大学生程序设计竞赛网络预选赛
- “正直角三角形” Contest2074 - 中南大学第九届大学生程序设计竞赛网络预选赛
- 中南大学第十一届大学生程序设计竞赛网络预选赛总结
- ACM/ICPC黑龙江省第四届大学生程序设计竞赛网络预选赛有感
- 第九届广东省大学生程序设计竞赛排名
- 湖南省第九届大学生程序设计竞赛
- 湖南省第九届大学生计算机程序设计竞赛
- 河南省第九届大学生程序设计竞赛 题解
- 虚拟机安装后TP框架验证码失效
- spring学习之路2
- 作为新手,关于APP启动时出现空白页才跳到启动页,解决办法如下
- JQuery EasyUI常用控件的禁用方法
- JAVA 注解(Annotation)详解
- 安徽大学第九届大学生程序设计竞赛 网络预选赛
- MongoDB 聚合管道(一)(Aggregation Pipeline)
- 可配置路径的excel导出工具类
- 用 Docker 构建、运行、发布一个 Spring Boot 应用
- android studio问题:installation failed with message INSTALL_CANCELED_BY_USER
- 通过随机函数生成一个随机的数组
- linux命令大全(9)--tar命令详细用法
- Android在webview中实现js交互
- ARM跑快了 --- 时钟初始化