26~~
// 比较函数,用于qsort升序排序
int cmp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
int main()
{
int t;
scanf("%d", &t); // 读取测试用例数量
while (t--)
{
int n;
scanf("%d", &n); // 读取每个测试用例的国家数量
int *a = (int *)malloc(n * sizeof(int)); // 动态分配数组
for (int i = 0; i < n; ++i)
{
scanf("%d", &a[i]); // 读取每个国家的土地数量
}
qsort(a, n, sizeof(int), cmp); // 对土地数量进行升序排序
// 数组 国家数量 类型长度 函数名
int max_s = 0;
for (int i = 0; i < n; ++i)
{
int s = n - i; // 计算当前可能的最大s
if (a[i] >= s)
{ // 检查当前土地数量是否满足s的要求
max_s = s;
break; // 找到最大s,后续无需继续遍历
}
}
printf("%d\n", max_s); // 输出结果
free(a); // 释放动态分配的内存
}
return 0;
收获:分析每个国家的土地需求。假设选了k个国家,那么对于其中任意一个国家来说:1.它需要和其他k-1个国家建交,每个建交需要对方一块土地,所以互建的话,自己需要提供k-1块土地(因为每个建交对方要在自己这里建大使馆,所以自己需要出k-1块给其他国家建馆)。2. 还要征用一块自己的土地作为备用大使馆。所以总共需要k-1 + 1 = k块土地。
所以,每个被选中的国家,必须至少有k块土地。但因为我们选的是k个国家,要让这k个国家都满足这个条件。那怎么保证呢?
这时候,把数组降序排序。排序后,前k个国家是土地最多的k个。这时候,第k个国家(数组里是a[k-1],因为索引从0开始)的土地数是这k个里最小的。如果这个最小的都满足>=k,那么前面的k-1个国家的土地数都比它大,也必然满足>=k。因为数组是降序排的,a[0]>=a[1]>=...>=a[k-1]。所以只要a[k-1]>=k,那么这k个国家都满足条件。
所以,我们要找最大的k,使得排序后第k个元素(a[k-1])的值>=k。那遍历k从1到n,检查每个k是否满足a[k-1]>=k,然后记录最大的那个k。
第二个例子,排序后的数组是10,9,9,8,7,6,5,3,3,2。遍历k=6时,a[5]=6>=6,满足。k=7时,a[6]=5<7,不满足。所以最大k是6。
所以这段代码的逻辑是:通过降序排序,使得前k个元素是最大的k个,然后检查第k个元素是否足够大(>=k),因为如果第k个足够,前面的更大,都满足。这样遍历所有可能的k,找到最大的符合条件的k。
浙公网安备 33010602011771号