【CS 1376】帕秋莉•诺蕾姬(Hash)
来源:互联网 发布:windows10引导ubuntu 编辑:程序博客网 时间:2024/06/06 21:00
【东方人物出没】qwq,hash可以搞得题目,对于换位没搞清楚,搞得真头疼qwq
题目描述 Description
在幻想乡,帕秋莉•诺蕾姬是以宅在图书馆闻名的魔法使。这一天帕秋莉又在考虑如何加强魔法咒语的威力。帕秋莉的魔法咒语是一个仅有大写字母组成的字符串,我们考虑从’A’到’Z’分别表示0到25的数字,于是这个魔法咒语就可以看作一个26进制数。帕秋莉通过研究发现,如果一个魔法咒语所代表的数能够整除10进制数M的话,就能够发挥最大的威力。若当前的魔法咒语并不能整除M,帕秋莉只会将其中两个字符的位置交换,尽量让它能够被M整除,当然由于某些咒语比较特殊,无论怎么改变都不能达到这个目的。请你计算出她能否只交换两个字符就让当前咒语被M整除。(首位的’A’为前导0) 第1行:1个字符串,长度不超过L。 第2行:1个正整数,M 第1行:用空格隔开的2个整数,输出时先输位置靠前的那个。 如果存在多种交换方法,输出字典序最小的,比如1 3和1 5都可以达到目的,就输出1 3;1 3和2 4都行时也输出1 3。注意字符串下标从左到右依次为1到L开始。如果初始魔法咒语已经能够整除M,输出”0 0”;若无论如何也不能到达目的输出”-1 -1”。 PATCHOULI 16 4 9 对于30%的数据:1 <= L <= 10, 1 <= M <= 100 对于50%的数据:除前面30%外,1 <= L <= 500, M = 5或25或26 对于100%的数据:1 <= L <= 2,000, 1 <= M <= 200,000
输入描述 Input Description
第1行:1个字符串,长度不超过L。 第2行:1个正整数,M
输出描述 Output Description
第1行:用空格隔开的2个整数,输出时先输位置靠前的那个。 如果存在多种交换方法,输出字典序最小的,比如1 3和1 5都可以达到目的,就输出1 3;1 3和2 4都行时也输出1 3。注意字符串下标从左到右依次为1到L开始。如果初始魔法咒语已经能够整除M,输出”00”;若无论如何也不能到达目的输出”-1-1”。
样例输入 Sample Input
PATCHOULI 16
样例输出 Sample Output
4 9
数据范围及提示 Data Size & Hint
对于30%的数据:1 <= L <= 10, 1 <= M <= 100 对于50%的数据:除前面30%外,1 <= L <= 500, M = 5或25或26 对于100%的数据:1 <= L <= 2,000, 1 <= M <= 200,000
解题思路:
把每一个字母按照从后往前对应从最后一位开始当做1位置,
将其按照 26字母中自己的序号×26的给定串位置-1次方 方式
eg:9*26^(0)+12*26^(1)+…(样例PATCHOULI 16从后面开始输入的效果)处理出初始的sum
然后在进行i和j的互换时,先将原来的sum减去i和j对应的值
再从小处枚举互换位置ij(为保证字典序) eg:i为1–>n,j为i+1–>n;
将其互换后代表的hash值加入sum,看sum%0是否为0,为0即为正确
注意运算之间一直要膜啊膜
代码如下:
#include <cstdio>#include <algorithm>#include<iostream> #include <cstring>#define RI register intusing namespace std;const int sz = 2017;char L[sz];int mod,l,k,v[sz];inline void hash(){ v[l] = 1; for(RI i = l - 1;i > 0;i --) { v[i] = v[i + 1] * 26; v[i] %= mod; } k = 0; for(RI i = 1;i <= l;i ++) { k *= 26; k += L[i] - 'A'; k %= mod; }}inline int _swap_(int i,int j){ int sum = k; sum -= (v[i] * (L[i] - 'A')) % mod; sum -= (v[j] * (L[j] - 'A')) % mod; sum += (v[i] * (L[j] - 'A')) % mod;sum %= mod; sum += (v[j] * (L[i] - 'A')) % mod;sum %= mod; return sum;}void check(){ if(k % mod == 0) { puts("0 0"); return; } for(RI i = 1;i < l;i ++) for(RI j = i + 1;j <= l;j ++) { if(_swap_(i,j) % mod == 0) { printf("%d %d\n",i,j); return; } } puts("-1 -1");}int main(){ scanf("%s %d",L+1,&mod); l = strlen(L + 1); hash(); check(); return 0;}
- 【CS 1376】帕秋莉•诺蕾姬(Hash)
- 【CS 1004】四子连棋(bfs+hash,良心带样例解释)
- CS..........................
- cs
- cs
- cs
- Cs
- cs
- cs
- cs
- CS
- cs
- cs,
- cs
- cs
- cs
- cs
- cs
- ByteBuffer字节序
- Ubuntu 14.04.5 ssh 以root 用户登录
- windows与linux下完成数据库的定时备份
- linux下安装jdk
- 【转载】C++引用详解及与指针异同点
- 【CS 1376】帕秋莉•诺蕾姬(Hash)
- 二进制中有多少个1-LintCode
- 聊聊 Redis 使用场景
- poj1006-枚举
- npm常用插件
- 理解依赖注入
- NIO初探
- MFC中窗口实现拖拽文件功能
- linux命令_文件管理_chown