200天1000题 (DAY 4)
作者:互联网
200天1000题 (DAY 4)
目前总题数: 17
目前CF分数: 1325
T1 (CF . Edu 121) B - Minor Reduction
/*
给你一个数字n
你可以进行一次操作: 将这个数字n相邻的两个数位相加并且放回原来的字符串
例如:10057 对 1 和 0 相加 得到 1057
例如: 998 对 9和8相加 得到 917
问,你必须操作一次的前提下,怎么能让这个数字尽量大?
*/
/*
思路:
贪心, 如果能加出一个两位数,那么直接替换并且输出,否则的话对头两个数位进行操作
*/
const int N = 1e6 + 10;
int calc(char a,char b){
return (a - '0') + (b - '0');
}
inline void sensei()
{
string s;
cin >> s;
int n = s.size();
s = " " + s;
for(int i=n-1;i>=1;i--){
if(calc(s[i],s[i+1]) >= 10){
for(int j=1;j<i;j++){
cout << s[j];
}
cout << calc(s[i],s[i+1]);
for(int j=i+2;j<=n;j++){
cout << s[j];
}
cout << endl;
return ;
}
}
cout << calc(s[1],s[2]);
for(int i=3;i<=n;i++){
cout << s[i] ;
}
cout << endl;
}
signed main()
{
int t;
cin >> t;
while(t --){
sensei();
}
return 0;
}
T2. (CF Edu #123) C - Increase Subarray Sums
/*
挺好的一个贪心
*/
const int N = 1e6 + 10;
inline void sensei()
{
int n, k;
cin >> n >> k;
vector<int> a(n + 1);
vector<int> f(n + 1, -inf_ll);
vector<int> pre(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
pre[i] = pre[i - 1] + a[i];
}
for (int l = 1; l <= n; l++) {
for (int r = l; r <= n; r++) {
f[r - l + 1] = max(f[r - l + 1], pre[r] - pre[l - 1]);
}
}
int ans = -inf_ll;
for (int i = 1; i <= n; i++) ans = max(ans, f[i]);
cout << max(ans,0ll) << ' ';
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= n; j++) {
if (j >= i) f[j] += k;
}
ans = -inf_ll;
for (int j = 1; j <= n; j++) ans = max(ans, f[j]);
cout << max(ans,0ll) << ' ';
}
cout << endl;
}
signed main()
{
int t;
fuckios
cin >> t;
while (t--) {
sensei();
}
return 0;
}
T3. (CF #820 DIV.3) D. Friends and the Restaurant
/*
题目大意:
给出一个数字n,表示有n个人
接着给出一个数组a,其中a[i]表示第i人将要花费多少钱
接着给出一个数组b,其中b[i]表示第i人现在有多少钱
他们要分组去吃饭,每个组至少有两个人,并且小组里的人的所有人的钱的总和都必须大于等于小组里所有人将要花费的金额的总和
问最多可以分出多少个小组?
*/
/*
题解:
观察了一波样例,发现只需要定义一个数组del[],del[i]表示第i个人的钱减去他将要花费的钱的数值。
对del[i]进行排序然后双指针即可。
*/
const int N = 1e6 + 10;
inline void sensei()
{
int n;
cin >> n;
vector<int> a(n+1);
vector<int> b(n+1);
for(int i=1;i<=n;i++){
cin >> a[i] ;
}
for(int i=1;i<=n;i++){
cin >> b[i];
}
vector<int> del(n+1);
for(int i=1;i<=n;i++){
del[i] = b[i] - a[i];
}
sort(del.begin()+1,del.begin()+n+1);
int l = 1;
int r = n;
int cnt = 0;
while(r > l){
if(del[r] + del[l] >= 0){
cnt++;
r--;
l++;
}else{
l++;
}
}
cout << cnt << endl;
}
signed main()
{
fuckios
int t;
cin >> t;
while(t --){
sensei();
}
return 0;
}
T4. (CF #793 DIV.2) LIS or Reverse LIS?
/*
题目大意:
给你一个长度为n的数组,可以对其任意排列,求其数组与反转数组的LIS中较小值的最大值
*/
/*
题解: 最开始没写出来,看了一下大佬的题解,发现还是自己观察问题的能力太弱了。
对于一组数来说例如样例中的
6
2 5 4 5 2 4
其中每个数都出现了两次
这启发了我们可以安排一半数字在LIS,另外一半给LDS , 2 4 5 5 4 2
所以在一个数组中我们可以对此计数
*/
struct sensei_hash {
// 哈希,unordered map 防卡
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
inline void sensei()
{
int n;
cin >> n;
int cnt = 0;
unordered_map<int,int,sensei_hash> mp;
for(int i=1;i<=n;i++){
int alls;
cin >> alls;
if(mp[alls] < 2){
// 计数,只有出现了两次或以内的才是对答案有贡献的
mp[alls]++;
cnt++;
}
}
// 结论: 答案就是 (cnt/2) 向上取整
if(cnt&1){
cout << (cnt+1) / 2 << endl;
}else{
cout << cnt / 2 << endl;
}
}
signed main()
{
int t;
cin >> t;
while(t --){
sensei();
}
return 0;
}
T5. (CF) 1646B - Quality vs Quantity
// 贪心
const int N = 1e5 + 10;
vector<vector<int>> g(N, vector<int>(6, 0));
vector<vector<int>> f(N, vector<int>(6, -inf_ll));
inline void sensei()
{
int n;
cin >> n;
vector<int> a(n+1);
ll sum = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
sum += a[i];
}
sort(a.begin() + 1, a.begin() + n + 1, greater<>());
int cnt = n / 2;
ll sum2 = 0;
for (int i = 1; i <= cnt; i++) {
sum2 += a[i];
}
if (n % 2 == 1 && sum2 > sum - sum2 || n % 2 == 0 && sum2 - a[cnt] > sum - sum2)cout << "YES" << '\n';
else cout << "NO" << '\n';
}
signed main()
{
int t;
cin >> t;
while(t--)
sensei();
return 0;
}
标签:200,cnt,return,int,--,vector,sensei,DAY,1000 来源: https://www.cnblogs.com/BeB0p/p/16701391.html