开哈希表存字母数量,一旦数目超过 ,就输出,水题
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
int main()
{
int n;
cin >> n;
unordered_map<string, int> hash;
for(int i = 0; i < n; i ++ )
{
string str;
cin >> str;
hash[str] ++ ;
if(hash[str] * 2 > n)
{
cout << str << endl;
break;
}
}
return 0;
}
构造一个圈,考察构造题型
在这里将七种颜色用0 ~ 6七个数字表示,我们先取前四种颜色进行排列,也就是0,1,2,3四个数字,最后将剩余的 3 个数字排列在最后,保证了任取四个数字都是不同的,不管是取0,1,2,3四个数字的区间段或者是包含 3 个数字排列在最后的区间段,都可以保证任取的四个数字不同。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
string a = "ROYGBIV";
int n;
cin >> n;
string res;
for(int i = 0; i < n - 3; i ++ )//n - 3空出四个位置出来
res += a[i % 4];
for(int i = 0; i < 3; i ++ )
res += a[i + 4];
cout << res << endl;
return 0;
}
经典的构造题,还有一个思路是先按顺序排7个剩下的最后四个随便排(这里的四个是题目限制)
算了,还是来代码看看吧
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
string a = "ROYGBIV";
int n;
cin >> n;
for(int i = 0; i < n / 7; i ++ )
cout << a;
a = "GBIVGBIV";
for(int i = 0; i < n % 7; i ++ ) cout << a[i];
cout << endl;
return 0;
}
题目大意:在图当中一共有多少种不同的轨迹
首先,每个不同的轨迹必然存在一个格子在上下左右四个边界上
反过来看,对于一个在边界上的格子必然在只能在同一个轨迹上
反证法
我们可以先考虑证明对于一个在边界上的格子能在两个轨迹上
首先对于在边界的点都有一个入度和出度,且是唯一的出入度
我们可以观察到路径是无限的,但格子是有限的,所以说最后棋子的路径会变成一个循环,这样我们可以看出与论点矛盾,故得出对于一个在边界上的格子必然在只能在同一个轨迹上。
每一个边上的格子最多只会在一个路径当中
之后就是用连通块进行判断了,采用并查集判断共有几个集合,就是几条不同的路径。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 4000010;
int n, m;
int p[N];
int get(int x, int y)
{
if(x == 1) return y;
if(y == m) return m + x - 1;
if(x == n) return m + n - 1 + m - y;
if(y == 1) return m + n - 1 + m - 1 + n - x;
return 0;
}
int find(int x)
{
if(p[x] != x) p[x] = find(p[x]);
return p[x];
}
int merge(int x, int y)
{
x = find(x), y = find(y);
p[x] = y;
}
int main()
{
cin >> n >> m;
for(int i = 1; i < 2 * (n + m) - 4; i ++ ) p[i] = i;
if(n > m) swap(n, m);
for(int i = 1; i <= m; i ++ )
{
if(i <= n)
{
merge(get(1, i), get(i, 1));
merge(get(n, i), get(n - i + 1, 1));
}
else
{
merge(get(1, i), get(n, i - n + 1));
merge(get(n, i), get(1, i - n + 1));
}
if(m - i + 1 <= n)
{
merge(get(1, i), get(m - i + 1, m));
merge(get(n, i), get(n - m + i, m));
}
else
{
merge(get(1, i), get(n, i + n - 1));
merge(get(n, i), get(1, i + n - 1));
}
}
int res = 0;
for(int i = 1; i <= 2 * (n + m) - 4; i ++ )
if(p[i] == i)
res ++ ;
cout << res << endl;
}
推公式法不是很会,在这里不做解释,想了解的读者可到弹球路径推公式查看