黑龙江农垦科技职业学院喜迎寒假多校联赛2
作者:互联网
数组截取
链接:https://ac.nowcoder.com/acm/contest/11471/A
来源:牛客网
题目描述
有一段数组n 从中截取和为k的一部分 最长可以截取多长?(如果截取不到正好为k的情况下输出-1)
注意:
出题人:出个数组截取吧;验题人:数据太弱了加强一下;出题人:陷入沉思,OK
本题因为验题人吐槽,数据太弱所以加强了一点点,一点点…
因为数据比较多 请使用你认为最快的读取方式 最省内存的运算方法。反正C++标程 500ms 256mb 内跑过去了。
输入描述:
第一行输入两个整数 n,k
1<n<=2×107
0<=k<=1018
第二行输入n个正整数(包含0)
a1 a2 …an (0<=ai<=1012) 1<=i<=n
输出描述:
输出运算结果
示例1
输入
复制
10 3
3 3 1 1 1 0 0 0 3 3
输出
复制
6
示例2
输入
复制
10 3
6 6 6 6 6 6 6 6 6 3
输出
复制
1
备注:
注意数据及其多 请使用快速的读取方式
以及内存很小 不要浪费 哦
很典型的双指针类型的题,但是数据范围有些大,凡是涉及区间求和得问题都可以用前缀和优化
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <ext/rope>
#include <bits/stdc++.h>
using namespace std;
#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
//#define x first
//#define y second
//int dx[4] = {0, 1, 0, -1};
//int dy[4] = {1, 0, -1, 0};
//typedef __int128 INT;
typedef pair<double, int> PDI;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
inline int read(int out = 0)
{
char c;
while((c=getchar()) < 48 || c > 57);
while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
return out;
}
const int N = 2e7 + 10;
const int M = 2e7 + 10;
const int mod = 77797;
const int PP = 13331;
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const double PI = acos(-1);
int n, k;
int a[N];
signed main(){
scanf("%lld%lld", &n, &k);
for (int i = 1; i <= n; i ++){
gt(a[i]);
}
int ans = -1;
int temp = 0;
for (int i = 1, j = 1; i <= n; i ++){
while(temp <= k && j <= n){
temp += a[j];
j ++;
}
// cout << temp << " " << j << endl;
if (temp - a[j - 1] == k && j <= n) ans = max(ans, j - i - 1);
else if (temp == k && j > n) ans = max(ans, j - i);
temp -= a[i];
}
cout << ans << endl;
return 0;
}
群友们在排列数字
链接:https://ac.nowcoder.com/acm/contest/11471/B
来源:牛客网
题目描述
群友们在玩一个游戏,共n个人在玩 每个人要在0-(n-1)中选一个数,注意每个数只能选择一次,
然后按照先后选择顺序拼成一个数,计算组成的数字是否可以整除k,
群友们想知道,如果选择方案不重复,最多有多少种情况可以整除k?
如果不可能整除k请输出-1;
输入描述:
第一行输入两个正整数 n,k
1<=n<=10,1<=k<=107
输出描述:
输出结果
示例1
输入
复制
2 1
输出
复制
2
说明
01 10 两种组合除以1都可以除开
很典型的dfs的题,先爆搜出来所有的排列组合,然后看这种排列组合的数是多少,并且看这个数能否整除k
我们需要设置两个参数,第一个是当前搜得了几个数,另外一个是当前搜得的数的组合是什么
void DFS(int x,int now) {
for(int i = 0 ; i < n ; i ++) {
if(book[i] == 0) {
book[i] = 1;
int Q = now;
now = now * 10 + i;
if(x == n) total+= ((now % k) == 0);
else DFS(x + 1,now);
now = Q;
book[i] = 0;
}
}
return ;
}
issue与lifehappy给学生分组
链接:https://ac.nowcoder.com/acm/contest/11471/D
来源:牛客网
issue与lifehappy在给学生分组 现在他们手里有一组n分学生量化好的数据a 这份数据是一个数字,代表学生的大致实力
他们要给学生分成m组并且要求总实力和的最大值最小(ccpc抢名额战略,分散一点)
不过学生们已经拉帮结派的排好队了 所以 issue与lifehappy只能选取这组数据中的连续队列。
输入描述:
第一行 n m n个学生 分成m组
1<=m<=n<=106
第二行为n正整数an
a1 a2 …an (0<=ai<=1011) 1<=i<=n(保证最终结果在ull内)
输出描述:
输出分组后总实力最大值的最小
示例1
输入
复制
5 3
1 8 9 4 2
输出
复制
9
凡是涉及最大值,最小值,最大值的最小值都要想一想二分出答案
一定要注意最后那一组还有一组!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <ext/rope>
#include <bits/stdc++.h>
using namespace std;
#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
//#define x first
//#define y second
//int dx[4] = {0, 1, 0, -1};
//int dy[4] = {1, 0, -1, 0};
//typedef __int128 INT;
typedef pair<double, int> PDI;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
inline int read(int out = 0)
{
char c;
while((c=getchar()) < 48 || c > 57);
while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
return out;
}
const int N = 2e6 + 10;
const int M = 2e7 + 10;
const int mod = 77797;
const int PP = 13331;
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const double PI = acos(-1);
int n, m;
int a[N];
int s[N];
bool check(int mid){
for (int i = 1; i <= n; i ++){
if (a[i] > mid) return false;
}
int last = 0, cnt = 0;
for (int i = 1; i <= n; i ++){
if (s[i] - s[last] > mid){
cnt ++;
last = i - 1;
if (cnt >= m) return false;
}
}
return true;
}
signed main(){
scanf("%lld%lld", &n, &m);
int maxd = 0;
for (int i = 1; i <= n ; i ++) scanf("%lld", &a[i]);
for (int i = 1; i <= n; i ++) maxd = max(maxd, a[i]);
for (int i = 1; i <= n; i ++) s[i] = s[i - 1] + a[i];
int l = maxd, r = 1e18;
while(l < r){
int mid = (l + r) / 2;
//cout << mid << "-----" << endl;
if (check(mid)) r = mid;
else l = mid + 1;
}
cout << l << endl;
return 0;
}
删删删越小越好
链接:https://ac.nowcoder.com/acm/contest/11471/E
来源:牛客网
题目描述
这一天Kadia与Majiagou在教学弟,
突然提出了一个问题 给你一个超大的数字 让你从中删掉几位 怎么让他最小?
这种签到题不会还有人写不出来吧 不会吧不会吧
输入描述:
第一行输入一个整数N
1<=len(N)<=2×107
第二行输入一个整数k代表删除几个数字
0<=k<=len(N)
输出描述:
输出结果
示例1
输入
复制
10000
1
输出
复制
0
说明
删掉1结果为0
示例2
输入
复制
12347897187194164979
10
输出
复制
1114164979
前面的数字越小越好,先找到保留最后的数字后,剩下的数字最小的往前放,大的堆在后面,如果有更小的,保证还剩下最少的个数并且前面有任的情况下,一直往前面放,很明显了,这是一道堆栈的题,模拟即可,记得去掉前导0
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <ext/rope>
#include <bits/stdc++.h>
using namespace std;
#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
//#define x first
//#define y second
//int dx[4] = {0, 1, 0, -1};
//int dy[4] = {1, 0, -1, 0};
//typedef __int128 INT;
typedef pair<double, int> PDI;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
inline int read(int out = 0)
{
char c;
while((c=getchar()) < 48 || c > 57);
while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
return out;
}
const int N = 2e7 + 10;
const int M = 2e7 + 10;
const int mod = 77797;
const int PP = 13331;
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const double PI = acos(-1);
char a[N];
int top;
signed main(){
ios;
string s;
int n;
cin >> s >> n;
int len = s.size() - n;
if (len == 0){
cout << "0" << endl;
return 0;
}
top = 0;
for (int i = 0; i < s.size(); i ++){
while(top && a[top - 1] > s[i] && n){
n --;
top --;
}
a[top ++] = s[i];
}
int idx = 0;
while(idx < len && a[idx] == '0'){
idx ++;
}
if (idx == len){
cout << "0" << endl;
return 0;
}
else{
for (int i = idx; i < len; i ++)
cout << a[i];
}
return 0;
}
happy的异或运算
链接:https://ac.nowcoder.com/acm/contest/11471/F
来源:牛客网
题目描述
我们都知道有一种位运算叫做异或,那么这道题是一道思维题。
给出一个整数n,请求出1-n之间选取两个数进行异或最大能得出多大?(两个数可以相同)
输入描述:
1 ≤ N ≤1018
输出描述:
无
示例1
输入
复制
10000
输出
复制
16383
示例2
输入
复制
648
输出
复制
1023
示例3
输入
复制
324
输出
复制
511
最大的肯定是都是1的情况多少位都是啥即可
Alan%%%
链接:https://ac.nowcoder.com/acm/contest/11471/G
来源:牛客网
题目描述
又是欢快的一天,牛客多校算法训练营4又在日常%Alan。qcjj想知道到底Alan被%了多少次,所以整理了一下聊天记录。
如果一句话中存在Alan,那么那句话中的%都算%了Alan。由于可能话中有空格,所以去掉空格后形成的Alan也算Alan。
输入描述:
第一行输入整数n表示聊天记录行数
1<=n<=1000
以下n行每行一个字符串s代表聊天记录
1<=s.length<=1000
输出描述:
输出%Alan次数
示例1
输入
复制
5
%alan%%
%Alan%%%
cdqwsq%% A l a n%%
%AC lan%%
%Alan%%%
输出
复制
12
读入一整行,用getlin,然后枚举把空格删了,最后看有多少%,再看是否有ALEN即可
int tail = 0;
getline(cin,a);
int len = a.length();
for(int i = 0 ; i < len ; i ++)
if(a[i] != ' ' && a[i] != '\n') tail ++ , S[tail] = a[i];
int cnt = 0,flag = 0;
for(int i = 1 ; i <= tail ; i ++) {
if(S[i] == '%') cnt ++;
if(S[i] == 'A' && S[i + 1] == 'l' && S[i + 2] == 'a' && S[i + 3] == 'n') flag = 1;
}
Ans += cnt * flag;
for(int i = 1 ; i <= tail ; i ++) S[i] = '\0';
return ;
标签:输出,int,多校,寒假,复制,喜迎,include,输入,define 来源: https://blog.csdn.net/qq_45772483/article/details/113060623