[Offer收割]编程练习赛51-灯光控制 相似的字符串

题目1 : 灯光控制

时间限制: 10000ms
单点时限: 1000ms
内存限制: 256MB

描述

小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 : 相似的字符串

时间限制: 10000ms
单点时限: 1000ms
内存限制: 256MB

描述

恺撒密码是一种古老的加密方法。它将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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值