本来这一周的练习是杭电的新生赛,但是很多同学没有及时的注册周赛,所以才有了这一场补充周赛,题目连接这里:swpu-acm集训队补充周赛,所以我就不把题目写出来了,话不多说,上题解:
A:题意无比明确啊,给你a,b,s三个数,求是否恰好用给定的s步内从(0,0)到(a,b),判断一下就好,从(0,0)到(a,b)最少需要abs(a-0)+abs(b-0)步,如果s小于这个值,肯定到不了啊,如果大于等于的话,判一下两者之前的差值是不是偶数啊,为什么要是偶数呢?因为我可以先花abs(a-0)+abs(b-0)步到(a,b),然后往任意一个方向走一步,再回来,2步,一直循环这样,只要为2的倍数(包括0,刚好到),一定可以回来,下面是代码#include <bits/stdc++.h>
using namespace std;
int main(){
int a,b,s;
while(~scanf("%d%d%d",&a,&b,&s)){
int x = abs(a-0);
int y = abs(b-0);
if(s < x+y) printf("No\n");
else{
if(abs(s-x-y)%2 == 0) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}
B:B题应该是比A题更容易思考到的,给你n个价值,问最少取多少个价值之和大于总价值的一半。从大到小排一下序,先存一个值的一半(偶数除2加一,因为要大于一半,奇数也是除2加一),然后在一个for里面累加的时候判断就行了#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int cmp(int a,int b){
return a > b;
}
int main(){
int n,a[105],sum = 0;
scanf("%d",&n);
for(int i = 0;i < n;i++){
scanf("%d",&a[i]);
sum+=a[i];
}
sum = sum/2+1;
int ans = 0;
sort(a,a+n,cmp);
for(int i = 0;i < n;i++){
ans += a[i];
if(ans >= sum) {printf("%d\n",i+1);break;}
}
return 0;
}C:给你n个学校的人数和公车最大载人数,判断最少需要几辆公车可以把所有的人载完,但是每个学校的同学要么全上,要么全不上,加的时候判断就行,因为每个学校的人数一定不大于公车最大载人数,所以,每个公车至少一个学校,那么直接把离当前最近的学校的同学全部拉上车,然后判断是否超载,是,则这一个学校的同学全部到另外的车上去,公车数量加一#include <bits/stdc++.h>
using namespace std;
int main(){
int n,m,a[105];
while(~scanf("%d%d",&n,&m)){
for(int i = 0;i < n;i++)
scanf("%d",&a[i]);
int sum = 0,ans = 1;
for(int i = 0;i < n;i++){
sum += a[i];
if(sum > m) ans++,sum = a[i];
}
printf("%d\n",ans);
}
return 0;
}D:本场防AK题?大模拟啊,因为猫和老鼠的移动方向是一样的,所以只需要写一个移动的函数,然后模拟逃亡的状态就行了,注意的是有可能猫永远抓不到老鼠,所以当你的时间超过某一个值的时候其实已经形成了一个循环,所以要稍微判断一下防止循环超时,代码量略大,但是其实只是无脑模拟而已,水题,具体情况看代码吧#include <stdio.h>
int main()
{
int MD,CD,MX,MY,CX,CY;
int t;
long time;
char map[10][11];
int i,j,k;
scanf("%d",&t);
while(t--)
{
MD = 0;
CD = 0;
time = 0;
for (i=0; i<10; i++)
scanf("%s",map[i]);
for (i=0; i<10; i++)
{
for (j=0; j<10; j++)
{
if (map[i][j] == 'c')
{
CX = i;
CY = j;
}
if (map[i][j] == 'm')
{
MX = i;
MY = j;
}
}
}
while (1)
{
if (MX == CX && MY == CY)
break;
switch (CD)
{
case 0:
if (CX-1<0||map[CX-1][CY] == '*')//上
{
CD++;
}
else
{
CX--;
}
break;
case 1:
if (CY+1 == 10||map[CX][CY+1] == '*')//右
{
CD++;
}
else
{
CY++;
}
break;
case 2:
if (CX+1 == 10||map[CX+1][CY] == '*')//下
{
CD++;
}
else
{
CX++;
}
break;
case 3:
if (CY-1<0||map[CX][CY-1] == '*')//左
{
CD=0;
}
else
{
CY--;
}
break;
}
switch (MD)
{
case 0:
if (MX-1<0||map[MX-1][MY] == '*')//上
{
MD++;
}
else
{
MX--;
}
break;
case 1:
if (MY+1 == 10||map[MX][MY+1] == '*')//右
{
MD++;
}
else
{
MY++;
}
break;
case 2:
if (MX+1 == 10||map[MX+1][MY] == '*')//下
{
MD++;
}
else
{
MX++;
}
break;
case 3:
if (MY-1<0||map[MX][MY-1] == '*')//左
{
MD=0;
}
else
{
MY--;
}
break;
}
time++;
if(time>100000)break;
}
if(time>100000) printf("0\n");
else
printf("%d\n",time);
}
return 0;
}E:给你n个数,判断有多少对数之和小于s,直接暴力写两个循环复杂度是2w*2w,4亿左右,肯定是不可取的,稍微优化一下,先从小到大排个序,然后一遍i,j从i+1开始循环,这样保证每次选的两个数不会重复,当a[i]+a[j] > s之后直接跳出循环,因为是从小到大排序,a[i]+a[j] > s,a[j+1] > a[j],a[i]+a[j+1] > s,所以后面的数都不用考虑,在i的循环里面当a[i]+a[i+1] > s时一定直接跳出,因为i到后面最小的和都是a[i]+a[i+1],因此不予考虑后面,代码如下:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
int n,s,a[20005];
int main(){
while(~scanf("%d%d",&n,&s)){
memset(a,0,sizeof(a));
for(int i = 0;i < n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
int count = 0;
for(int i = 0;i < n-1;i++){
if(a[i]+ a[i+1] > s) break;
for(int j = i+1;j < n;j++){
if(a[i] + a[j] > s) break;
else count++;
}
}
printf("%d\n",count);
}
return 0;
}集训队的各位还要好好加油啊,AK1位,大二的hhz,4题的6位。大家加油
swpu-acm集训队补充周赛(2016/12/24)题解
原创Nemaleswang 博主文章分类:swpu各种周赛题解及信息通知 ©著作权
©著作权归作者所有:来自51CTO博客作者Nemaleswang的原创作品,请联系作者获取转载授权,否则将追究法律责任
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
第六届·2024 MindSpore 量子计算黑客松热身赛赛题解读
开发者可以全面体验全新一代通用量子计算框架MindSpore Quantum。
量子计算 MindSpore MindSpore Quantum -
SWPU-ACM集训队周赛之个人赛(3-18)----题解
今天的比赛题目不是特别简单,但是也有3题是水题系列,另外的三题学的比较努力的同学一
swpu-acm集训队 算法竞赛 ACM 题解 i++ -
SWPU-ACM集训队周赛之个人赛(4-3,蓝桥杯模拟赛)----题解
今天的比赛题目是今年蓝桥杯的模拟赛原题,所以题解大概是可以在网上给搜索到的,但是希望同学们都是本着上是给
ACM swpu-acm集训队 算法竞赛 题解 acm-icpc -
ACM国家集训队论文
组合数学计数与统计2001 - 符文杰:《Pólya原理及其应用》2003 -
信息学竞赛 搜索 动态规划