题意:
这一天,TT因为疫情在家憋得难受,在云吸猫一小时后,TT决定去附近自家的山头游玩。
TT来到一个小湖边,看到了许多在湖边嬉戏的鸭子,TT顿生羡慕。此时他发现每一只鸭子都不一样,或羽毛不同,或性格不同。TT在脑子里开了一个map<鸭子,整数> tong,把鸭子变成了一些数字。现在他好奇,有多少只鸭子映射成的数的数位中不同的数字个数小于k。
思路:
这道题的数据范围就是一个坑!!!其实k最大也就是10。我郁闷了半天,最后也没提交代码,唉!
通过mod 10的方法取得每一位,最后统计出现过的数字个数就可以了。
代码:
#include
using namespace std;
const int maxn = 11;
int n, k, a[maxn], ans;
int main()
{
scanf("%d %d", &n, &k);
for (int i = 1; i <= n; i++)
{
long long x = 0;
scanf("%lld", &x);
while (x)
{
a[x % 10]++;
x /= 10;
}
int temp = 0;
for (int j = 0; j < 10; j++)
{
if (a[j])
{
temp++;
a[j] = 0;
}
}
if (temp < k)
ans++;
}
printf("%d\n", ans);
//system("pause");
}
题意:
据传,2020年是宇宙射线集中爆发的一年,这和神秘的宇宙狗脱不了干系!但是瑞神和东东忙于正面对决宇宙狗,宇宙射线的抵御工作就落到了ZJM的身上。假设宇宙射线的发射点位于一个平面,ZJM已经通过特殊手段获取了所有宇宙射线的发射点,他们的坐标都是整数。而ZJM要构造一个保护罩,这个保护罩是一个圆形,中心位于一个宇宙射线的发射点上。同时,因为大部分经费都拨给了瑞神,所以ZJM要节省经费,做一个最小面积的保护罩。当ZJM决定好之后,东东来找ZJM一起对抗宇宙狗去了,所以ZJM把问题扔给了你~
思路:
就是求解最小最大值问题,枚举每个点到其他点的距离,然后取最大值,再对于所有的最大值取最小值。O(n^2)解决问题。
值得注意的是,题目是要距离的平方,好坑。
代码:
#include
#include
#include
using namespace std;
const int maxn = 1000 + 10;
int n;
struct Node
{
int x, y;
} node[maxn];
double distance(Node a, Node b)
{
return pow(a.x - b.x, 2) + pow(a.y - b.y, 2);
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
cin >> node[i].x >> node[i].y;
double ans = 0;
double tnt = 0;
int m = 0;
for (int i = 1; i < n; i++)
ans = max(ans, distance(node[0], node[i]));
for (int i = 1; i < n; i++)
{
tnt = 0;
for (int j = 0; j < n; j++)
{
if (i == j)
continue;
tnt = max(tnt, distance(node[i], node[j]));
}
if (ans > tnt)
ans = tnt, m = i;
else if (ans == tnt && (node[i].x < node[m].x || (node[i].x == node[m].x && node[i].y < node[m].x)))
m = i;
}
cout << setiosflags(ios::fixed) << setprecision(2);
cout << node[m].x << ".00"
<< " " << node[m].y << ".00" << endl;
cout << ans;
//system("pause");
}
题意:
在瑞神大战宇宙射线中我们了解到了宇宙狗的厉害之处,虽然宇宙狗凶神恶煞,但是宇宙狗有一个很可爱的女朋友。
最近,他的女朋友得到了一些数,同时,她还很喜欢树,所以她打算把得到的数拼成一颗树。
这一天,她快拼完了,同时她和好友相约假期出去玩。贪吃的宇宙狗不小心把树的树枝都吃掉了。所以恐惧包围了宇宙狗,他现在要恢复整棵树,但是它只知道这棵树是一颗二叉搜索树,同时任意树边相连的两个节点的gcd(greatest common divisor)都超过1。
但是宇宙狗只会发射宇宙射线,他来请求你的帮助,问你能否帮他解决这个问题。
思路:
这题自己一开始是没有思路的,后来想了想,可以用区间dp的方法去做。
我们定义两个数组:l[i][j],r[i][j]分别表示以i为根,向左到j可以作为i的左子树,向右到j可以作为i的右子树。这是表示的树结构,所以非常重要。
然后用dp[i][j]表示i∼j能构成一棵树。函数最后返回dp[1][n]]。
当l[k][i]==r[k][j]==true时,dp[i][j]=true,此时i∼j是以k为根的二叉搜索树。
状态转移方程如下:
#include
#include
#include
#include
using namespace std;
const int maxn = 700 + 100;
int t, n, a[maxn];
bool dp[maxn][maxn], g[maxn][maxn], l[maxn][maxn], r[maxn][maxn];
int gcd(int _a, int _b) { return _b == 0 ? _a : gcd(_b, _a % _b); }
bool IsBinarySearchTree()
{
for (int len = 1; len <= n; len++)
{
for (int i = 1; i <= n - len + 1; i++)
{
int j = i + len - 1;
for (int k = i; k <= j; k++)
{
if (l[k][i] && r[k][j])
{
dp[i][j] = true;
l[j + 1][i] |= g[j + 1][k];
r[i - 1][j] |= g[i - 1][k];
}
}
}
}
return dp[1][n];
}
int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
memset(l, false, sizeof(l));
memset(r, false, sizeof(r));
memset(dp, false, sizeof(dp));
for (int i = 1; i <= n; i++)
{
l[i][i] = r[i][i] = dp[i][i] = true;
for (int j = 1; j <= n; j++)
g[i][j] = gcd(a[i], a[j]) > 1;
}
if (IsBinarySearchTree())
printf("Yes\n");
else
printf("No\n");
}
return 0;
}