2015 CCC - 02 找不匹配

照例传送门CNUOJ - 0385:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=355

题目分析:首先感谢”数据结构与算法“群群友的支持与鼓励,没有你们的点拨&鼓励我不可能搞出来的。

这道题如果是暴力枚举循环节的话,可能数据会坑你一下……(只有一个循环节即两数互质= =)那就挂了……暴力好像也能拿30分吧。

这道题算法的雏形是Kael大神弄出来的,他是这么跟我说的:

假设是|T|>|S|,因为|A|=|B|,所以S与T的比较周期有|T|个,再检查S中的每个字符与T中字符不一样的个数,就得到所有周期比较完后的个数,然后把S中每个字符的个数加起来就是答案,如果|A|大于了|T|和|S|的最小公倍数,就把答案乘以M/|T|,M/|T|又是新一轮周期。

为什么S与T的比较周期有|T|个呢?通俗的说就是S中的每个字符都会跟T中的每个字符进行对位一次,而再次当S第一个字符与T第一个字符对位时,就是进行了|T|个周期了。

看不懂是吧?知道你也不会好好看,我来给你分析一下= =

比如这两个长度互质的串:

把长度标上后,让我们关注一下S串头元素进行了哪几次比较:

可以看到共有4次比较(用深绿色圆圈表示),我们发现这不就是T串里的4个元素吗?

好,那我们看看在T串上S的头元素是怎么比较的:

上面四个是S串,底下的是T串。我们来举一个例子:

所以说头元素贡献了3份答案。

那么显而易见,不仅S串头元素会全都比较T串的四个元素,第二个、第三个元素也会比较,我们再画一个清晰的图:

上面是S串,下面是T串,先让上面最左边的”a“进行一次全部比较,可以看到有2个答案。

第二个元素同理有三个答案。

第三、第四个S串里的”a“元素答案一定和answer1是一样的(想一想,为什么?)

最后根据加法、乘法原理,答案应该是:3 * answer1 + 1 * answer2 = 3 * 2 + 1 * 3 = 9;

画回最原始的图再看一眼:

答案正确。此输入应该是:5 4 abaa abbaa 输出是:9

那如果输入的是10 8 abaa abbaa呢?

那么就应该有两个循环节了,答案是18。

那么至此为止,两字串长度互质的情况我们已经会算了,可以用两个哈希表vis_S[27], vis_T[27]分别表示26个小写字母在S串和T串中分别出现了几次。

程序不难写出,建议读者好好看一眼哈希表的使用,为下边打好基础:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 using namespace std;
  5
  6 void read(int& x)
  7 {
  8     x = 0;
  9     int sig = 1;
 10     char ch = getchar();
 11
 12     while(!isdigit(ch))
 13     {
 14         if(ch == ‘-‘) sig = -1;
 15         ch = getchar();
 16     }
 17
 18     while(isdigit(ch))
 19     {
 20         x = x * 10 + ch - ‘0‘;
 21         ch = getchar();
 22     }
 23
 24     return ;
 25 }
 26
 27 int tot;
 28
 29 long long ans;
 30
 31 const int maxn = 1000000 + 10;
 32
 33 char S[maxn], T[maxn];
 34 int T1, T2;
 35
 36 int vis[2][27];
 37
 38 int read_str1()
 39 {
 40     char tmp = getchar();
 41
 42     while(!isalpha(tmp)) tmp = getchar();
 43
 44     tot = 0;
 45
 46     while(isalpha(tmp))
 47     {
 48         S[tot++] = tmp;
 49
 50         vis[0][tmp - ‘a‘]++;
 51
 52         tmp = getchar();
 53     }
 54
 55     S[tot] = ‘\0‘;
 56     return tot;
 57 }
 58
 59 int read_str2()
 60 {
 61     char tmp = getchar();
 62
 63     while(!isalpha(tmp)) tmp = getchar();
 64
 65     tot = 0;
 66
 67     while(isalpha(tmp))
 68     {
 69         T[tot++] = tmp;
 70
 71         vis[1][tmp - ‘a‘]++;
 72
 73         tmp = getchar();
 74     }
 75
 76     T[tot] = ‘\0‘;
 77     return tot;
 78 }
 79
 80 void vis_init()
 81 {
 82     long long tmp;
 83
 84     for(int i = 0; i < 27; i++)
 85     {
 86         tmp = 0;
 87         for(int j = 0; j < 27; j++)
 88         {
 89             if(i == j) continue;
 90             tmp += vis[1][j];
 91         }
 92         ans += vis[0][i] * tmp;
 93     }
 94
 95     return ;
 96 }
 97
 98 int main()
 99 {
100     read(T1);
101     read(T2);
102
103     int s1 = read_str1();
104     int s2 = read_str2();
105
106     vis_init();
107
108     ans = (long long)((double)ans * ((double)T1 / (double)s2));
109     //记得是同时约了一个s1
110
111     printf("%lld\n", ans);
112
113     return 0;
114 }

好,那么我们来看看非互质的情况:

时间: 2024-08-07 08:37:18

2015 CCC - 02 找不匹配的相关文章

2015.11.02 学习 Ubuntu下安装gosublime插件及其配置

2015.11.02 学习 Ubuntu下安装gosublime插件及其配置 1.Ctrl+shift+P 打开package control 输入pcip 回车 2.出现的框中输入gosublime,回车 3.preferences---package setting--gosublime--setting default 打开后在env{}中添加GOROOT和GOPATH 4.保存后全部复制到preferences---package setting--gosublime--setting

02:找第一个只出现一次的字符

02:找第一个只出现一次的字符 总时间限制: 2017-07-1218:36:28 1000ms 内存限制:  65536kB 描述 给定一个只包含小写字母的字符串,请你找到第一个仅出现一次的字符.如果没有,输出no. 输入 一个字符串,长度小于100000. 输出 输出第一个仅出现一次的字符,若没有则输出no. 样例输入 abcabd 样例输出 c错误答案:9分 #include<stdio.h> #include<iostream> #include<algorithm&

【转换博客通知】(本博客2015.08.02停用)

2015.08.02 本博客停用,搬运至 http://tonyfang.is-programmer.com/ 感谢各位对我的支持!

深入浅出WPF之Binding--笔记(2015.03.02)

Binding DataContext属性被定义在FrameworkElement类里,这个类是WPF的基类,这意味着所有WPF控件都具备这个属性.在UI树上,每个结点都有DataContext.当一个Binding只知道Path而不知道Source时,会沿着UI树一路向树的根部找过去,每路过一个结点就查看该结点的DataContext是否具有Path所指定的属性.若有,那就把该对象作为自己的Source,否则继续找下去.如果到了树的根部还没有找到,那该Binding就没有Source,因而不会

使用c#正则验证关键字并找出匹配项

在.net里,使用类Regex可以正则验证一些关键字并取出匹配项. 1.使用Regex.IsMatch(string  input,  string  pattern,  RegexOptions  options)匹配输入字符串与指定的正则表达式是否符合条件: 返回类型:bool true——满足匹配条件  false——不满足匹配条件 input:string类型,输入项 pattern:string类型,指定的正则表达式 options:可选,枚举值,设置正则表达式选项 例:验证字符串中是

【正则表达式】——02单个字符匹配

[前言]本节主要讲述匹配单个字符 1. 匹配纯文本 区分大小写 匹配纯文本和搜索功能一致 2. 匹配任意字符——“.” .匹配除了换行符以外的任意字符 注意: [元字符]特殊符号和字符,即所谓的元字符,给予了正则表达式强大的功能和灵活性, 正则表达式是由字符组成的字符串,这些字符可以是文本字符(真正的文本),也可以是元字符(含有特殊含义的字符) 原文地址:https://www.cnblogs.com/testxiaobai/p/10762173.html

2015.12.02今天的一些感受

首先我是个刚转入前端没几天菜鸟,今天第一个感触,前端真是太深奥了!原来前端的东西这么多! <embed id="svgEle" src="svg/svg2.svg" style="width: 100%; height: 99%;" type="image/svg+xml"/> var svgEle = document.getElementById("svgEle");//获得svgEle标签

记忆碎片2015.03.02

有时候家人也会做错事情,毁了孩子的一生,这也是中国特色吧.我会坚决的改变中国特色,至少自己的命运不能总被中国特色笼罩,别认输,因为认真生活,你就赢了.幸福是争取来的,才安稳恒久,我会好好争取幸福.

Deepin 2015 安装后找不到win10 启动选项的解决办法

#sudo vi /boot/grub/grub.cfg 在export linux_gfx_mode后面加 menuentry "Windows 10 (loader)" --class windows --class os { insmod part_gpt insmod ntfs set root='hd0,gpt4' if [ x$feature_platform_search_hint = xy ]; then search --no-floppy --fs-uuid --s