CFS ROUDN 762 水题记录
这里是平时水水比赛的流水账式思路记录,如果有值得研究的题则会另写详细题解。(代码在文末)
点这里进入比赛
Problem A - Square String?
签到
Problem B - Squares and Cubes(平方和立方)
求范围内平方根和立方根的数量,没多想,我的做法是遍历一下1e9内所有平方根和立方根记录到vector里,然后排个序得到1 4 8 9。。。。,t只有20,所有每次样例都去找找看所求的范围在这个数组里到哪里就可以了。
Problem C - Wrong Addition
一道模拟题(也可以dfs?),模拟一种特殊的减法运算,模拟题的难点不在于模拟不出来而是少考虑一个点,这次cfs我就是卡死在了这个点上(鬼知道我在干嘛。。。)。
这道题就是借位求差,细心点都能模拟出来,给的例子也把大部分坑给出来了,唯一可能错的应该就是没考虑到连借两位吧,比如说103 - 8,由于第二位是0很可能模拟时借位借到了13-8。
Problem D - New Year’s Problem
思维题吧,有点贪心的意思,题目略长但题意很好看。
我们需要考虑的是少一个商店的情况,比赛时第一反应就是求每一个friend可以拿到的最大值(也就是p数组每一列的最大值),也要看看每一个商店最大和第二大的那个值是多少(每一行的最大和次大),可惜没细想。事实上这道题就是求p数组(每一行的次大值 的 最大值) 和 (每一列的最大值 的最小值),然后取小值。细品下挺有意思的。
二分做法:https://blog.csdn.net/weixin_51159301/article/details/122094875
Problem E - MEX and Increments
貌似比赛时这道题做对的人更多,或许是因为D思路比较奇妙吧,🙈。
参考代码:
/*
* @Author: Retr0.Wu
* @Date: 2021-12-20 22:42:45
* @Last Modified by: Retr0.Wu
* @Last Modified time: 2021-12-21 01:47:26
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void solveA()
{
string s;
int t;
cin >> t;
while (t--)
{
cin >> s;
if (s.length() & 1)
{
cout << "NO" << endl;
}
else
{
string s1 = s.substr(0, s.length() / 2);
string s2 = s.substr(s.length() / 2);
cout << (s1 == s2 ? "YES" : "NO") << endl;
}
}
}
void solveB()
{
map<ll, int> M;
int flag1 = 1;
vector<int> v;
for (int i = 1; i <= 1000000000; i++)
{
ll sq = i * i;
if (sq > 1000000000)
break;
if (M.count(sq) == 0)
{
M[sq] = 1;
v.push_back(sq);
}
if (flag1)
{
ll cu = i * i * i;
if (cu > 1000000000)
{
flag1 = 0;
}
else
{
if (M.count(cu) == 0)
{
M[cu] = 1;
v.push_back(cu);
}
}
}
}
sort(v.begin(), v.end());
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
if (n == 1000000000)
{
cout << 32591 << endl;
continue;
}
for (int i = 0; i < v.size(); i++)
{
if (n < v[i])
{
cout << i << endl;
break;
}
}
}
}
void solveC()
{
string str[10] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
int t;
cin >> t;
while (t--)
{
string a, s;
cin >> a >> s;
int lenA = a.length();
int lenS = s.length();
int i = lenA - 1;
int j = lenS - 1;
int tp = 0;
int jie = 0;
string ans = "";
// s - a
int flag = 1;
while (j >= 0)
{
int ai;
if (i < 0)
ai = 0;
else
ai = a[i] - '0';
tp = s[j] - '0';
if (jie)
{
tp = tp * 10 + s[j + 1] - '0';
if (tp < ai)
{ // 防止越2位
flag = 0;
break;
}
}
//cout<<ai<<" "<<tp<<endl;
if (tp >= ai)
{
jie = 0;
if (tp - ai >= 10)
{
flag = 0;
break;
}
ans = str[tp - ai] + ans;
i--;
}
else
{
jie = 1;
}
j--;
}
if (flag && i < 0)
{
int ind = ans.size() - 1;
for (int i = 0; i < ans.size(); i++)
{
if (ans[i] != '0')
{
ind = i;
break;
}
}
cout << ans.substr(ind) << endl;
}
else
{
cout << "-1" << endl;
}
}
}
void solveD()
{
int t;
cin >> t;
while (t--)
{
int m, n;
cin >> m >> n;
vector<vector<int> > p(m);
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
int tp;
cin >> tp;
p[i].push_back(tp);
}
}
vector<int> maxp(n);
int minn = 0x3f3f3f3f; // 每一列的最大值 的最小值
int maxx = 0; // 每一行的次大值 的 最大值
for (int j = 0; j < n; j++)
{
maxp[j] = 0;
for (int i = 0; i < m; i++)
{
maxp[j] = max(maxp[j], p[i][j]); // 每一列的最大值
}
minn = min(minn, maxp[j]);
}
for(int i =0;i<m;i++){
vector<int> vtp = p[i];
sort(vtp.begin(),vtp.end());
maxx = max(maxx,vtp[n-2]);
}
if (n - 1 >= m) // 如果friend数足够多,那就不需要考虑怎么选择商店最合适,直接每个friend都去选择对与他们最好的商店即可,也就是直接求minn
{
cout << minn << endl;
}
else{
cout << min(minn,maxx)<<endl; // 必有一个商店需至少承担俩个购买量,该商店的次大值必将是拉低joy的可能因素,与上一种情况的最小值一起求min即可
}
}
}
int main()
{
solveD();
return 0;
}