2015苏州大学ACM-ICPC集训队选拔赛(3)题解
1001
考虑前半组数,我们只需要标记每个数出现的次数,再加上这个数之前的数出现的次数,即为这个数在m次操作中总共需要翻转的次数(即求前缀和),再根据翻转的奇偶性判断最后这个位置上的数有没有翻转即可。后半组数的处理方法类似。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
int s[];
int m,n,vis[]={},d[]={};
int main()
{ while(scanf("%d%d",&n,&m)!=EOF)
{
memset(vis,,sizeof(vis));
for(int i=;i<n;i++)
scanf("%d",&s[i]);
for(int i=;i<m;i++)
{
scanf("%d",&d[i]);
}
sort(d,d+m);
for(int i=;i<m;i++)
{
vis[d[i]-]++;
vis[n-d[i]]++;
}
for(int i=;i<n/;i++)
{
vis[i]+=vis[i-];
vis[n-i-]+=vis[n-i];
}
for(int i=;i<n;i++)
{
if(i>)
printf(" ");
if(vis[i]%==)
printf("%d",s[i]);
else
printf("%d",s[n-i-]);
}
printf("\n");
}
return ;
}
1002
很明显环中的最大值为a与b的最小公倍数,最小值为最大公因数。需要理论证明的同学请私戳学长。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
ll Gcd(ll a,ll b)
{
return b?Gcd(b,a%b):a;
}
int main()
{
ll a,b;
while(scanf("%lld %lld",&a,&b)!=EOF)
{
ll gcd=Gcd(a,b);
ll lcm=a/gcd*b;
printf("%lld\n",lcm-gcd);
}
return ;
}
1003
对于一个n*n的棋盘,我们分两种情况讨论:
第一种情况,n是一个奇数。那么这种时候,棋盘有一个中心点,且总格子数为偶数。
第二种情况,n是一个偶数。那么这种时候,棋盘没有中心点,且总格子数为偶数。
当n为偶数时,无论先手如何行动,后手只要保持与其 关于棋盘中心对称 放子,那么就已经是后手的必胜态。具体说明如下:
马的攻击范围,是与马成3*2或2*3的矩形的 与马对称的顶点。设n*n棋盘上每个格子坐标依次为(1,1)(1,2)…(n,n),倘若先手选择把棋子放置在(i,j)格上,那么后手相对称的放置方法为,放置在(n+1-i,n+1-j)上。现在我们来证明后手总是可 以在(n+1-i,n+1-j)上落子。
因为格子的坐标都是整数,所以不可能存在先手放置在(i,j)的马能吃到(n+1-i,n+1-j)的情况。又因为开局时棋盘是关于中心对称的,而每一回合后手总是跟随先手对称落子,所以每回合棋盘的各个格子的状态必然是关于棋盘 中心对称的。
所以易知,当先手能够把棋子放置在(i,j)格上的时候,后手总是可以在(n+1-i,n+1-j)上落子的。即,只要先手还能放,那下一步后手肯定也能放。
所以,最终先找不到合适位置落子的必然是先手。所以后手 保持与先手关于棋盘中心对称放子 是一种必胜的方法。所以先手无论如何放子,都是先手的必败态。
当n为奇数时,先手若选择放置在整张棋盘的中心点,而后跟随后手对称落子,则是先手的必胜态。具体说明方法与n为偶数时类似,不再赘述。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
if(n%==)
cout<<<<endl;
else
cout<<<<endl;
}
return ;
}
1004
这是一道二进制题,题目上已经有提示了。n个树坑可以看成是n位二进制数,没有种树的位置上值为0,种树的位置上值为1。这样只需要枚举所有的n位二进制数,求出每一位上的值,再判断是否至少有1以及任意两个1之间是否距离至少为m。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring> using namespace std;
int a[]; int main()
{
int n,m,k;
while(~scanf("%d%d%d",&n,&k,&m))
{
int ans=;
for(int i=;i<(<<n);++i)
{
int cnt=;
memset(a,,sizeof(a));
int num=i;
while(num!=)
{
a[cnt++]=num%;
num=num/;
}
int count=,pos=;
num=;
bool f=true;
for(int j=;j<cnt;++j)
{
if(a[j]==)
{
if(num<m&&pos!=)
f=false;
count++;
num=;
pos++;
}
else
num++;
}
if(f&&count>=k)
ans++;
}
printf("%d\n",ans);
}
return ;
}
1005
签到题。将所有给出的数转化成10进制数,注意a~f的情况。用一个长度为1000的数组保存每个数出现的次数,最后遍历一遍数组找到出现次数最多的数即可。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring> using namespace std;
int num[];
char a[]={'a','b','c','d','e','f'};
int main()
{
int t,n;
char s[];
while(~scanf("%d",&t))
{
memset(num,,sizeof(num));
while(t--)
{
scanf("%d %s",&n,s);
int c=;
for(int i=;i<strlen(s);++i)
{
if(s[i]>=''&&s[i]<='')
{
c=c*n;
c+=s[i]-'';
}
else
{
c=c*n;
c+=s[i]-'a'+;
}
}
num[c]++;
}
int max=;
int ans=;
for(int i=;i<=;++i)
{
if(num[i]>max)
{
max=num[i];
ans=i;
}
}
printf("%d\n",ans);
}
return ;
}
1006
很经典的一道题,也算是签到题。解决这道题的方法很多,这里就只给出最优的方案。我们需要保存一个当前最大的子序列和maxsun以及从1开始的子序列的和thissum。当thissum>maxsum时,maxsum赋值为thissum,当thissum<0时,thissum赋值为0。这样遍历一遍数组,thissum每次加上遍历到的数,并进行更新,最后maxsum保存的便是最大的子序列和。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std; int main()
{
long long ThisSum,MaxSum,i,a,n;
while(~scanf("%d",&n))
{ ThisSum = MaxSum = ;
for( i= ; i<n ; i++ )
{
scanf("%I64d",&a);
ThisSum += a; if( ThisSum > MaxSum )
MaxSum = ThisSum ;
else
if( ThisSum < )
ThisSum = ;
}
printf("%I64d\n",MaxSum);
}
return ;
}
1007
这道题是鼓励大家勇于提交的,给的两串数其实是没有规律的。而测试样例只有一组,那么唯一的可能就是测试样例在已经给出的数对里面。那么只要判断读入的字符串究竟是其中的哪一个就行了。
#include<stdio.h>
#include<string.h>
char a[][]={
"",
"",
"",
"",
"",
"",
"",
"",
"",
""
};
char b[][]={
"",
"",
"",
"",
"",
"",
"",
"",
"",
""
};
int main(){
char s[];
scanf("%s",s);
for(int i=;i<;i++){
if(strcmp(s,a[i])==)
puts(b[i]);
}
}
1008
这道题是对凯撒加密的频数攻击,即依次枚举26个密钥,尝试用这些密钥将文章解密,得到26篇文章,然后比较这26篇文章与统计规律进行比较,找出最符合要求的文章即可。
重点是如何从26篇文章中筛选出最接近统计规律的文章。通常用的是如下的方法:
1、设p[i]表示26个字母中第i个字符的统计规律里的频率,我们计算所有26个字母对应的p[i]^2之和,这个值大约是0.065
2、设q[i]表示用当前密钥k解密后的文章中第i个字符的实际频率,我们计算sigma(p[i]*q[i])得到一个相关值m
3、对于26个密钥,找出相关值最接近0.065的那个密钥,那么这个就是最后的结果。
#include<cstdio>
#include<cmath>
#include<cstring>
char c[];
double table[]={0.08167,0.01492,0.02782,0.04253,0.12702,0.0228,0.02015,0.06094,0.06966,0.00153,0.00772,0.04025,0.02406,0.06749,0.07507,0.01929,0.00095,0.05987,0.06327,0.09056,0.02758,0.00978,0.02360,0.00150,0.01974,0.00074};
double f[];
int cnt[]={};
int len,num;
void fun(){
for(int i=;i<len;i++){
if(c[i]>='a'&&c[i]<='z'){
cnt[c[i]-'a']++;
num++;
}else if(c[i]>='A'&&c[i]<='Z'){
cnt[c[i]-'A']++;
num++;
}
}
for(int i=;i<;i++){
f[i]=1.0*cnt[i]/num;
}
int key;
double k=;
for(int i=;i<;i++){
double test=;
for(int j=;j<;j++){
test+=table[(j-i+)%]*f[j];
}
if(fabs(test-0.065)<k){
key=i;
k=fabs(test-0.065);
}
}
for(int i=;i<len;i++){
if(c[i]>='a'&&c[i]<='z'){
putchar((c[i]-'a'-key+)%+'a');
}else if(c[i]>='A'&&c[i]<='Z'){
putchar((c[i]-'A'-key+)%+'A');
}else{
putchar(c[i]);
}
}
}
int main(){
//freopen("in.txt","r",stdin);
len=num=;
char tmp;
while(true){
tmp=getchar();
if(tmp==EOF||tmp=='#'){
fun();
len=num=;
memset(c,,sizeof c);
memset(cnt,,sizeof cnt);
if(tmp==EOF)
break;
putchar('#');
}else{
c[len++]=tmp;
}
}
}
1009
基本照着题目的要求写即可,有以下几个注意点:
1、1也是个无聊的数
2、输入的x和y的大小不确定,需要先比较一下
3、对于能表示成a^2+b^2的这个条件,实际上我们可以证明,一个奇素数,如果能够表示成为上述形式,那么当且仅当他模4的余数为1。如果没发现这个定理,其实打表也是可以卡时间过的。
#include<cstdio>
using namespace std;
const int maxi=;
bool vis[maxi];
int sum[maxi];
int main(){
sum[]=;
sum[]=;
for(int i=;i<maxi;i++){
sum[i]=sum[i-];
if(!vis[i]){
if((i%==||i==)&&i%!=){
sum[i]++;
}
for(int j=;i*j<maxi;j++){
vis[i*j]=true;
}
}
}
int a,b;
while(scanf("%d%d",&a,&b)==){
if(a>b){
printf("%d\n",sum[a]-sum[b-]);
}else{
printf("%d\n",sum[b]-sum[a-]);
}
}
}
1010
一道模拟题,按照要求写,但是如果对每个样例都循环k次,那么这显然会超时。实际上对于每组输入并不需要循环这么多次,一般循环几次后就会看到循环的终点了,这里有两个终点,153和0,循环到这里就可以停了。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int maxi=;
int fun(int n,int k){
int cnt=;
while(true){
if(n==)
return ;
if(n==)
return ;
n-=n%;
n+=n%==?:(-n%);
int tmp=;
while(n>){
tmp+=(n%)*(n%)*(n%);
n/=;
}
n=tmp;
cnt++;
if(cnt==k)
return n;
}
}
int main(){
int n,k;
while(scanf("%d%d",&n,&k)==)
printf("%d\n",fun(n,k));
}
2015苏州大学ACM-ICPC集训队选拔赛(3)题解的更多相关文章
- 2014 ACM/ICPC 北京邀请赛 部分 题解
题目链接:http://acm.bnu.edu.cn/bnuoj/problem.php?search=2014+ACM-ICPC+Beijing+Invitational+Programming+C ...
- hihocoder1257(构造)(2015北京ACM/ICPC)
题意: 给你n条蛇,a[i]的长度为i,要求组成一个矩形.奇数蛇可折叠奇数次,偶数蛇折叠偶数次,然后按蛇的次序输出 (即一条蛇的输出只能是一个方向的) 2 3 1 2 1 3 2 3 1 1 2 1 ...
- 2015 ACM / ICPC 亚洲区域赛总结(长春站&北京站)
队名:Unlimited Code Works(无尽编码) 队员:Wu.Wang.Zhou 先说一下队伍:Wu是大三学长:Wang高中noip省一:我最渣,去年来大学开始学的a+b,参加今年区域赛之 ...
- ACM ICPC 2015 Moscow Subregional Russia, Moscow, Dolgoprudny, October, 18, 2015 G. Garden Gathering
Problem G. Garden Gathering Input file: standard input Output file: standard output Time limit: 3 se ...
- ACM ICPC 2015 Moscow Subregional Russia, Moscow, Dolgoprudny, October, 18, 2015 D. Delay Time
Problem D. Delay Time Input file: standard input Output file: standard output Time limit: 1 second M ...
- hdu 5444 Elven Postman(二叉树)——2015 ACM/ICPC Asia Regional Changchun Online
Problem Description Elves are very peculiar creatures. As we all know, they can live for a very long ...
- 2016 ACM/ICPC Asia Regional Qingdao Online(2016ACM青岛网络赛部分题解)
2016 ACM/ICPC Asia Regional Qingdao Online(部分题解) 5878---I Count Two Three http://acm.hdu.edu.cn/show ...
- (并查集)Travel -- hdu -- 5441(2015 ACM/ICPC Asia Regional Changchun Online )
http://acm.hdu.edu.cn/showproblem.php?pid=5441 Travel Time Limit: 1500/1000 MS (Java/Others) Memo ...
- (二叉树)Elven Postman -- HDU -- 54444(2015 ACM/ICPC Asia Regional Changchun Online)
http://acm.hdu.edu.cn/showproblem.php?pid=5444 Elven Postman Time Limit: 1500/1000 MS (Java/Others) ...
- 2015 ACM/ICPC Asia Regional Changchun Online HDU 5444 Elven Postman【二叉排序树的建树和遍历查找】
Elven Postman Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...
随机推荐
- org.apache.hadoop.security.AccessControlException: Permission denied: user=?, access=WRITE, inode="/":hadoop:supergroup:drwxr-xr-x 异常解决
进行如下更改:vim /usr/local/hadoop/etc/hadoop/hdfs-site.xml[我的hadoop目录在/usr/local下,具体的是修改你的hadoop目录中的/etc/ ...
- LuaFramework内存资源管理器ResourceManger详解及切换场景资源清理
1.成员变量 m_BaseDownloadingURL : 获取资源的地方,加载AssetBundle包的时候会用到 m_AssetBundleManifest : 包间依赖关系文件,从这个类中的信息 ...
- swift 3.0 基础练习 面向对象 类
模拟需求 创建100个女朋友 1.用面向对象思想 2.名字随机 3.年龄随机 4.拥有约会功能 5.将所有女朋友信息输出 class GirlFirend: NSObject { var name:S ...
- Redis数据类型之ZSet(五)
前言:有序集合zset跟其他类型一样,同样有几种编码方式.主要有两种编码方式,REDIS_ENCODING_ZIPLIST和REDIS_ENCODING_SKIPLIST.ziplist可以表示较小的 ...
- 消息队列NetMQ 原理分析5-StreamEngine、Encord和Decord
消息队列NetMQ 原理分析5-StreamEngine,Encord和Decord 前言 介绍 目的 StreamEngine 发送数据 接收数据 流程分析 Encoder V2Encoder V1 ...
- python-插入排序
所谓插入排序,就是检查第i个数字,若比它的左边的数字小,则进行交换,一直持续这个动作,直到它的左边的数字比它还要小,则停止. #coding:utf-8def insertion_sort(nums) ...
- 12. leetcode 455.Assign Cookies
Assume you are an awesome parent and want to give your children some cookies. But, you should give e ...
- C++标准库string
C++标准库string 定义和初始化 string s1 默认初始化,s1是一个空串 string s2(s1) s2是s1的副本 string s2 = s1 等价于s2(s1),s2是s1的副本 ...
- python--DenyHttp项目(1)--GUI:tkinter☞ module 'tkinter' has no attribute 'messagebox'
AttributeError: module 'tkinter' has no attribute 'messagebox' improt tkinter from tkinter import * ...
- Fluent Validation with Web Api 2
using FluentValidation;using FluentValidation.Attributes;using System;using System.Collections.Gener ...