题目1 : 灯光控制
描述
小Hi学校的礼堂有N × M盏灯,排成N行M列的矩阵。
为了给校庆联欢晚会增加气氛,小Hi编写了一段程序控制灯光效果:
0. 晚会开始时,小Hi会手动点亮位于(X, Y)的灯;
1. (X, Y)被点亮后,位于(X+A, Y+B)、(X+2A, Y+2B)、(X+3A, Y+3B) ... 的灯(如果该位置存在灯)也会被依次点亮;
2. (X, Y)被点亮后,位于(X+C, Y+D)、(X+2C, Y+2D)、(X+3C, Y+3D) ... 的灯(如果该位置存在灯)也会被依次点亮;
给定ABCD,初始时所有灯都是熄灭的。假设晚会开始时小Hi点亮了位于(X, Y)的灯,请你计算最终一共有多少盏灯是亮着的。
输入
第一行包含4个整数,N, M, X, Y。
第二行包含4个整数,A, B, C, D。
对于50%的数据,1 ≤ N, M ≤ 1000
对于100%的数据, 1 ≤ N, M ≤ 1000000000, 1 ≤ X ≤ N, 1 ≤ Y ≤ M, -1000000 ≤ A, B, C, D ≤ 1000000
输出
最终亮着的灯的数目。
4 4 2 2 1 1 0 1样例输出
5
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
ll n,m,x,y;
ll a,b,c,d;
ll work(ll a,ll b)
{
ll res=0;
if(a==0&&b==0)
{
return 0;
}
else if(a==0&&b!=0)
{
if(b>0)
res=(m-y)/b;
else
res=(y-1)/b*(-1);
}
else if(a!=0&&b==0)
{
if(a>0)
res=(n-x)/a;
else
res=(x-1)/a*(-1);
}
else if(a>0&&b>0)
{
res=min((n-x)/a,(m-y)/b);
}
else if(a<0&&b>0)
{
res=min((x-1)/a*(-1),(m-y)/b);
}
else if(a>0&&b<0)
{
res=min((n-x)/a,(y-1)/b*(-1));
}
else if(a<0&&b<0)
{
res=min((x-1)/a*(-1),(y-1)/b*(-1));
}
return res;
}
int main(void)
{
scanf("%lld%lld%lld%lld",&n,&m,&x,&y);
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
ll gcd1=__gcd(a,b);
ll gcd2=__gcd(c,d);
ll res=0;
if(a==0&&c==0)
{
if(b>0&&d>0)
res=work(0,__gcd(b,d));
else if(b<0&&d<0)
res=work(0,(-1)*__gcd(b*(-1),d*(-1)));
else
res=work(0,b)+work(0,d);
}
else if(b==0&&d==0)
{
if(a>0&&c>0)
res=work(__gcd(a,c),0);
else if(a<0&&c<0)
res=work((-1)*__gcd(a*(-1),c*(-1)),0);
else
res=work(a,0)+work(c,0);
}
else
{
ll res1=work(a,b);
ll res2=work(c,d);
res=res1+res2;
}
if(1.0*a/b==1.0*c/d && a!=0 &&b!=0 && c!=0 && d!=0)
res-=work(a*c/__gcd(a,c),b*d/__gcd(b,d));
printf("%lld\n",res+1);
return 0;
}
题目2 : 相似的字符串
描述
恺撒密码是一种古老的加密方法。它将26个英文字母'A'-'Z'向左循环移动K位,得到新的密码表。
例如K=2,有:
ABCDEFGHIJKLMNOPQRSTUVWXYZ CDEFGHIJKLMNOPQRSTUVWXYZAB
则用'C'替代'A','D'替代'B'……
对于两个只包含大写字母的字符串A和B,如果A和B长度相同,并且A可以通过某种(某个K)恺撒加密得到B,我们就认为A和B是相似的。
例如"ABC"与"DEF"相似,"HI"与"ZA"相似。显然"相似"关系具有传递性和对称性。
给定N个字符串,请你将相似的字符串聚成一类,并输出最终有几个不同的类别。
输入
第一行包含一个整数N。
以下N行每行包含一个字符串S。S只包含大写字母。
对于50%的数据,1 ≤ N ≤ 100,N个字符串总长度不超过10000。
对于100%的数据,1 ≤ N ≤ 100000,N个字符串总长度不超过1000000。
输出
一个整数表示答案。
6 ABC DEF ZAB HIHO JKJQ NONU样例输出
2
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 1e5+100;
char s[maxn];
map<string,int>mp;
int main(void)
{
int n;
scanf("%d",&n);
int flag=0,res=0;
for(int i=0;i<n;i++)
{
scanf("%s",s);
int len=strlen(s);
if(len==1) {flag=1;continue;}
string temp="";
for(int j=1;j<len;j++)
{
char ss=((s[j]-s[0]+26)%26+'0');
temp=temp+ss;
}
if(mp[temp]==0) res++;
mp[temp]=1;
}
printf("%d\n",res+flag);
return 0;
}