一、A题
写的有些麻烦了,本人找的时候用的快排递归找的第k个数,其实排序找就够用了。
#include<bits/stdc++.h>
using namespace std;
const int N = 505;
int a[N];
int q[500*500+5];
void quick_sort(int *q, int l, int r, int k) {
if (l >= r) return;
int i = l - 1, j = r + 1, x = q[(l + r) >> 1];
while (i < j) {
do i++;
while (q[i] < x);
do j--;
while (q[j] > x);
if (i < j) swap(q[i], q[j]);
}
int len = j - l + 1; // 左侧长度
if (k <= len)
quick_sort(q, l, j, k); // 左侧
else
quick_sort(q, j + 1, r, k - len); // 右侧
}
void solve() {
memset(q, 0, sizeof(q));
memset(a, 0, sizeof(a));
int n,k;
cin>>n>>k;
for (int i=0;i<n;i++) {
cin>>a[i];
}
int t=1;
for (int i=0;i<n;i++) {
for (int j=0;j<n;j++) {
q[t++]=a[i]+a[j];
}
}
quick_sort(q,1,t - 1,k);
cout<<q[k]<<"\n";
}
int main() {
ios_base::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int T;
cin>>T;
while (T--) {
solve();
}
return 0;
}
二、I题
这个题是a题的升级版,用到了两次二分算法;
思路:
1.第一个二分(rescal中)二分查找答案 即第k大的组合的大小是多少。
2.第二个二分(count中)依次遍历数组中的每个元素,对各个元素查找差值从而找到小于target的所有组合方案,并相加传回。
#include <bits/stdc++.h>
// #define
using namespace std;
typedef long long ll;
// const int N = 1e5+5;
ll count(const vector<ll>& a, ll target) {
int n = a.size();
ll cnt = 0;
for (int i = 0; i < n; ++i) {
ll x = target - a[i];
int l = 0, r = n;
while (l < r) {
int mid = l + r >> 1;
if (a[mid] > x) {
r = mid;
} else {
l = mid + 1;
}
}
cnt += l;
}
return cnt;
}
ll rescal(vector<ll>& a, int k) {
sort(a.begin(), a.end());
ll l = 2 *a[0];
ll r = 2 * a.back();
while (l<r) {
ll mid = l + (r-l >> 1);
ll n =count(a,mid);
if (n >= k) {
r = mid;
}else {
l = mid + 1;
}
}
return l;
}
void solve() {
int n, k;
cin >> n >> k;
vector<ll> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
cout << rescal(a, k) << '\n';
}
int main() {
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int T;
cin >> T;
while (T--) {
solve();
}
return 0;
}
三、L题
模拟,不说了
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[70];
void init() {
int k = 1;
int sum = 1;
for (int i = 1; i <= 60; i++) {
if (i % 2==0) {
k*=2;
sum+=k;
a[i]=sum;
}else {
sum+=k;
a[i]=sum;
}
}
}
void solve() {
int m;
cin>>m;
cout<<a[m]<<'\n';
}
signed main() {
ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL);
int T;
cin>>T;
a[0]=1;
init();
while (T--) {
solve();
}
return 0;
}
四、K题
不难,但作者忘了当时是怎么写的了 。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5+5;
int v[N],c[N];
signed main() {
ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL);
int n;
cin>>n;
for (int i=1;i<=n;i++) {
cin>>v[i];
}
c[n+1]=-1,v[n+1]=-1;
for (int i=1;i<=n;i++) {
cin>>c[i];
}
int sum=0;
int last=c[1];
int t=0;
for (int i=1;i<=n+1;i++) {
if (last==c[i]) {
t=max(t,v[i]);
last=c[i];
}else {
sum+=t;
last=c[i];
t=v[i];
}
}
cout<<sum<<'\n';
return 0;
}
五、J题
全排列+字符串匹配
你不会想让我手搓kmp算法吧,对不起,find函数解决问题。
想看kmp算法的看作者另一篇,点击这里
#include<bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL);
string s;
cin>>s;
string wd[5];
for (int i=0;i<5;i++) {
cin>>wd[i];
}
bool vis[5]={0};
vector<string> str;
function<void(int)>dfs=[&](int i) {
if (i==5) {
string si="";
for (int j=0;j<5;j++) {
si+=str[j];
}
if (s.find(si)!=string::npos) {
cout<<"Nooo, la polizzia\n";
exit(0);
}
}
for (int j=0;j<5;j++) {
if (!vis[j]) {
str.push_back(wd[j]);
vis[j]=1;
dfs(i+1);
vis[j]=0;
str.pop_back();
}
}
};
dfs(0);
cout<<"Sargento Camelas, Gracias!\n";
return 0;
}
六、F题
结论:要求的边也就是质因数分解后的长度,分解后判断各个边大小要小于题目中的要求就yes,反正printf(“Que es Obo?\n”);数量就是分解后的质数和(相同的也算)。
#include<bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL);
int a,x1;
scanf("%d%d",&a,&x1);
// vector<int> v;
int n=0;
for (int i=2;i*i<=a;i++) {
if (a%i==0) {
int s=0;
while (a%i==0) {
a/=i;
s++;
}
n += s;
if (i>x1) {
printf("Que es Obo?\n");
return 0;
}
}
}
if (a>1) n++;
if (a>x1) {
printf("Que es Obo?\n");
return 0;
}
printf("%d\n",n);
return 0;
}
七、E题
单调栈,很经典的单调栈,求右边第一个比它小的数。
读好题目很关键,作者原来一直以为只是i和i+1进行比较呢,可恶的英语。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+5;
int d[N],e[N];
bool vis[N];
int main() {
ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL);
int n;
cin>>n;
for(int i=1;i<=n;i++) {
cin>>d[i];
}
for(int i=1;i<=n;i++) {
cin>>e[i];
}
stack<int>st;
vector<int>ne_small(n+1);
for(int i=1;i<=n;i++) {
while (!st.empty() && d[st.top()]>d[i]) {
ne_small[st.top()]=i;
st.pop();
}
st.push(i);
}
while(!st.empty()) {
vis[st.top()]=1;
st.pop();
}
int ans=1;
vector<int>v;
for (int i=1;i<n;i++) {
if (vis[i]) {
ans++;
v.push_back(i);
continue;
}
if (e[i]>e[ne_small[i]]) {
ans++;
v.push_back(i);
}
}
v.push_back(n);
cout<<ans<<'\n';
for (int i=0;i<v.size();i++) {
cout<<v[i]<<' ';
}
return 0;
}
1028

被折叠的 条评论
为什么被折叠?



