思路:定义一个stirng接受数字,遍历string,用一个size为10的数组来记录出现过的数字。
#include <iostream>
#include <string>
using namespace std;
int ans;
bool number[10];
int getNumber(string s)
{
int len = s.length(), cnt = 0;
for (int i = 0; i < len; i++)
{
if (!number[s[i] - '0']) cnt++;
number[s[i] - '0'] = true;
}
return cnt;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int n, k; cin >> n >> k;
while (n--)
{
memset(number, 0, sizeof(number));
string s; cin >> s;
ans += getNumber(s) < k;
}
cout << ans;
}
反思:一开始用了set,超时了,set会增加log的复杂度(更好笑的是我想了好久不用stl怎么做
思路:用二维数组a记录下每两点之间的距离。这道题是要找出距离最远的点最近的点,那只要遍历每个点并更新ans即可。
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <iomanip>
using namespace std;
const int MAXN = 1e3 + 5;
long long a[MAXN][MAXN];
long long getDistance(pair<int, int> p1, pair<int, int> p2)
{
return pow(p1.first - p2.first, 2) + pow(p1.second - p2.second, 2);
}
int main()
{
int N; cin >> N;
pair<int, int> ansPoint(1000009, 1000009);
long long maxTrue = 1e15;
vector<pair<int, int>> v;
for (int i = 0; i < N; i++)
{
int x, y; cin >> x >> y;
v.push_back(make_pair(x, y));
}
for (int i = 0; i < N - 1; i++)
for (int j = i + 1; j < N; j++)
a[i][j] = a[j][i] = getDistance(v[i], v[j]);
for (int i = 0; i < N; i++)
{
a[i][i] = 0;
double theMax = *max_element(a[i], a[i] + N);
if ((theMax < maxTrue) || (theMax == maxTrue && v[i] < ansPoint))
{
maxTrue = theMax;
ansPoint = v[i];
}
}
cout << fixed << vectorprecision(2) << (double)ansPoint.first << ' '
<< (double)ansPoint.second << endl
<< (double)maxTrue;
}
思路:一个dp题,一颗树的解决方案可以甩锅给两个子树,剩下的问题就是判断根和两个子节点是否满足最大共有大于1的条件。为了省时间,先算出两个数之间的最大公约数是否>1,存在bool数组g中。我用的递归dp,所以把算出来的结果存在数组中。
具体来说,递归函数bool solve(int b, int r, int e),含义是解决左段为l,根为r,右端为e的情况是否能构成一颗树,先递归判断左,即solve(b,k,r-1),其中k为[b,r-1]的任意值,再用同样方法判断右,如果可行,返回true。
#include <iostream>
#include <vector>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int MAXN = 700 + 5;
int a[MAXN];
bool g[MAXN][MAXN];
bool record1[MAXN][MAXN];
bool record2[MAXN][MAXN];
bool b1[MAXN][MAXN];
bool b2[MAXN][MAXN];
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
bool solve(int b, int r, int e)
{
if (!b1[b][r])
{
b1[b][r] = true;
if (b == r) record1[b][r] = true;
for (int i = b; i < r; i++)
if (solve(b, i, r - 1) && g[r][i])
{
record1[b][r] = true;
break;
}
}
if (!record1[b][r]) return false;
if (!b2[r][e])
{
b2[r][e] = true;
if (r == e) record2[r][e] = true;
for (int i = r + 1; i <= e; i++)
if (solve(r + 1, i, e) && g[r][i])
{
record2[r][e] = true;
break;
}
}
return record2[r][e];
}
int main()
{
int t; cin >> t;
while (t--)
{
memset(record1, 0, sizeof(record1));
memset(record2, 0, sizeof(record2));
memset(b1, 0, sizeof(b1));
memset(b2, 0, sizeof(b2));
int n; cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
for (int i = 0; i < n - 1; i++)
for (int j = i; j < n; j++)
g[i][j] = g[j][i] = gcd(a[i], a[j]) > 1;
bool flag = false;
for (int i = 0; i < n; i++)
if (solve(0, i, n - 1))
{
flag = true;
break;
}
if (flag) cout << "Yes";
else cout << "No";
if (t) cout << '\n';
}
}
反思:写右子树情况的时候,复制的左子树,有一处忘了改了,找了好半天的错。