【题目描述】
有一些字母卡片,每张卡片上都有一个小写字母,所以卡片组成一个字符串s。
现希望这些卡片拼凑出一些回文,但是要有以下要求:
1.每张卡片只能使用一次;
2.要求构成的回文串的数量最少。
现在想知道这些字母卡片,最少能拼凑出多少个回文。
例如:s="abbaa",输出1, 因为最少可以拼凑出“ababa”这一个回文串;
s=“abc”,输出3, 因为最少只能拼凑出“a”、“b”、“c”这三个回文串。
【输入描述】
输入包括一行,一个字符串s,字符串s长度length(1<=length<=1000),s中每个字符都是小写字母。
【知识回顾】
“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。
首先,这道题分解成:1. 字母能否构成回文串;2. 最少拼凑成几个字符串。
对1.来说,回文串中字母先后顺序不同,则回文串不同。我的思路是:不考虑字母先后,借鉴桶排序思想,统计每个字母出现次数,出现奇数次的只能在奇数位,剩余的左右填充。(想的不全,还是借鉴了官方例子。)
【官方答案】
统计每种字符的数量,然后提取一个奇数个数的字符放在第一个回文串中心,对于每个剩下的字符,两个相同字符放在回文串左右,直接用每种字符的数量对2取余即可,如果还有剩下的单一字符都只能单独为一个回文串。
#include "stdafx.h"
#include
#include
#include
#include
#include
#include
using namespace std;
void main()
{
string s;
cin >> s;
vector t(26);
for (char c:s)
{
t[c-'a']++;
}
int ans = 1;
for (int i=0;i<26;i++)
{
if (t[i] & 1)
{
t[i]--;
break;
}
}
for (int i=0;i<26;i++)
{
t[i]%=2;
}
for (int i=0;i<26;i++)
{
if (t[i])
{
ans++;
}
}
cout<
t[26] 一共26个字母,统计每个字母出现次数。
char c:s 相当于 定义一个遍历字符c,让它分别等于字符串s里面的各个字符,然后执行下面的语句,当c被赋值为s里面所有字符各一次后,就会退出这个循环.
& 、&&
区别
对于整型,&
和 | 计算操作数的按位“与”;
对于 bool 操作数,& 或 | 计算操作数的逻辑“与”、“或”;
也就是说对于bool类型 & 和&&、| 和 || 的if判断结果是相同的。
对于整形数据&&只判断真假(0或非0),两边的数据必须都为真或任一方为假;
对于整形数据&两边的数据则进行按位与运算,并返回计算结果让if判断这个值
逻辑(AND): true && false : false
按位(AND): 1001 0110 & 1111 1111 : 1001 0110 (二进制位)
t[i] & 1 按位与(二进制),把奇数个的挑出-1