题目链接
A - Alex Origami Squares
水题
题意:给定一个长方形,在长方形内部画三个相同的正方形,问正方形的边长最大是多大。
题解:根据长宽比例可以算出三种情况,如果长比宽大三倍以上,那么正方形边长就是宽;如果长在宽的1.5倍到3倍之间,那么正方形边长就是长/3;如果长在宽的1到1.5倍之间,那么就看做是在长方形内部画一个田字,正方形边长就是宽/2
#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int main()
{
freopen("alex.in","r",stdin);
freopen("alex.out","w",stdout);
int n,m;
while(cin>>n>>m)
{
double ans;
if(n<m)
swap(n,m);
if(n>=3.0*m)
ans=m*1.0;
else if(n>=3.0*m/2.0)
ans=n*1.0/3.0;
else
ans=m*1.0/2.0;
printf("%.6f\n",ans);
}
return 0;
}
B - Black and White
题意:给定X,Y,分别表示由’.‘和’@'组成的连通块的个数。
思路:假如X<Y,我们用两部分来构造这个结果,第一部分由一个’.‘连通块和Y-(X-1)割’@‘连通块组成,第二个部分由X-1个’.‘连通块和X-1个’@'连通块组成.
#include<bits/stdc++.h>
using namespace std;
const int maxn=10010;
char s[1111][111];
int main()
{
freopen("black.in","r",stdin);
freopen("black.out","w",stdout);
int r,c;
cin>>r>>c;
r--;
c--;
int i,j;
for(i=0; i<500; i++)
{
for(j=0; j<100; j++)
{
s[i][j]='@';
}
}
for(i=500; i<1000; i++)
{
for(j=0; j<=100; j++)
{
s[i][j]='.';
}
}
for(i=0; i<500; i+=2)
{
for(j=0; j<100; j+=2)
{
if(!c)
break;
s[i][j]='.';
c--;
}
if(!c)
break;
}
for(i=501; i<1000; i+=2)
{
for(j=0; j<100; j+=2)
{
if(!r)
break;
s[i][j]='@';
r--;
}
if(!r)
break;
}
printf("1000 100\n");
for(i=0; i<1000; i++)
{
for(j=0; j<100; j++)
{
printf("%c",s[i][j]);
}
printf("\n");
}
return 0;
}
C - Concatenation
题意:
AA中取出一个前缀,BB中取出一个后缀,问问拼出多少个字符串
思路:
感觉很巧妙的一道题。
首先能构造出的字符串总数为 lena∗lenblena∗lenb。
那么假设从AA中取出的前缀结尾字符为xx,那么从BB中取出的后缀首字符为xx的有mm个,那么将AA的结尾去掉或者将BB的首部去掉,拼成的字符串是一样的,也就是重复算了mm次。
假设AA中结尾为字符xx的有nn个,那么对于字符xx来说,一共多算了n∗mn∗m次。
所以统计出AA中前缀结尾字符出现次数和BB中所有后缀开头字符出现次数,减去所有相同字符个数乘积。
但是注意A串第一个字符和B串最后一个字符不统计,因为首字符往前和尾字符往后是空的,发生不了重复。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<bits/stdc++.h>
using namespace std;
char a[100100],b[100100];
long long int x,y,z,i,j,c[26],d[26],m,n;
int main()
{
freopen("concatenation.in","r",stdin);
freopen("concatenation.out","w",stdout);
scanf("%s%s",a,b);
x=strlen(a);
y=strlen(b);
m=x*y;
for(z=1; z<x; z++)
c[a[z]-'a']++;
for(z=0; z<y-1; z++)
d[b[z]-'a']++;
for(z=0; z<26; z++)
{
if(c[z]!=0&&d[z]!=0)
m-=c[z]*d[z];
}
printf("%lld\n",m);
return 0;
}
E - Easy Arithmetic
题意:给定一个长度不超过1000的字符串表达式,向该表达式中加入’+‘或’-’,使得表达式的值最大,输出该表达式。
题解:比如300-456就改成300-4+56,遇到二位数以上的减数的情况就变成-首位+剩下的,这样会使得表达式值最大。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<bits/stdc++.h>
using namespace std;
char s[10000];
int x,y,z,i,j,m,n;
int main()
{
freopen("easy.in","r",stdin);
freopen("easy.out","w",stdout);
scanf("%s",s);
while(s[z]!='\0')
{
if(s[z]=='-')
{
z++;
printf("-%c",s[z]);
z++;
while(s[z]=='0')
{
printf("+0");
z++;
}
if(s[z]>='0'&&s[z]<='9')
{
printf("+");
while(s[z]>='0'&&s[z]<='9')
{
printf("%c",s[z]);
z++;
}
}
}
else
{
printf("%c",s[z]);
z++;
}
}
return 0;
}
H - Hash Code Hacker
由于s[i]⋅31n−1−i+s[i+1]⋅31n−2−i=(s[i]+1)⋅31n−1−i+(s[i+1]−31)⋅31n−2−i ,故只要第i位不是′z′和′Z′,且第i+1位是一个不是′z′的小写字母,那么第i位加一,第i+1位变为这个小写字母对应的大写字母再加一即得到两个hash值相同的不同字符串,初始给1000个位置全部赋为′a′,每次对于不同的i进行上述操作即可得到至多1000个hash值相同的字符串
#include<iostream>
#include<cstdio>
#include<cstring>
#include<bits/stdc++.h>
using namespace std;
int main()
{
freopen("hash.in","r",stdin);
freopen("hash.out","w",stdout);
int n;
cin>>n;
int i,j;
for(i=1; i<=n; i++)
{
for(j=1; j<=1000; j++)
{
if(i==j+1&&i!=1)
printf("%c",'G' - 1);
else if(i==j&&i!=1)
printf("%c",'G' + 31);
else
printf("G");
}
printf("\n");
}
return 0;
}
L - Lucky Chances
水题
规模很小,暴力判即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<bits/stdc++.h>
using namespace std;
int a[105][108];
int x,y,z,i,j,m,n,sum;
int main()
{
freopen("lucky.in","r",stdin);
freopen("lucky.out","w",stdout);
scanf("%d %d",&x,&y);
for(i=1; i<=x; i++)
for(j=1; j<=y; j++)
scanf("%d",&a[i][j]);
for(i=1; i<=x; i++)
for(j=1; j<=y; j++)
{
for(m=i-1; m>=1; m--)
if(a[m][j]>=a[i][j])break;
if(m==0)sum++;
for(m=i+1; m<=x; m++)
if(a[m][j]>=a[i][j])break;
if(m==x+1)sum++;
for(m=j-1; m>=1; m--)
if(a[i][m]>=a[i][j])break;
if(m==0)sum++;
for(m=j+1; m<=y; m++)
if(a[i][m]>=a[i][j])break;
if(m==y+1)sum++;
}
cout<<sum;
return 0;
}
反思:
1.第一题虽然是水题,但是没有注意到需要文件的输入输出,导致wa了好多遍,以后需要多加注意
2.题目中有样例只是进行辅助理解题意的作用,并没有最后输出的格式,不能想当然
3.算法技巧掌握的还是太少,要继续学习