A.找出最大的两个数 注意ll
#include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!! ") #define pb push_back #define inf 1e9 //std::ios::sync_with_stdio(false); using namespace std; //priority_queue<int,vector<int>,greater<int>> que; const double EPS = 1.0e-8; const double eps = 1.0e-8; typedef pair<int, int> pairint; typedef long long ll; typedef unsigned long long ull; const int maxn = 3e5 + 10; const int maxm = 300; const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}}; //next_permutation ll a[100005],b[100005]; int main() { //freopen("in.txt", "r", stdin); int n; ll sum=0; cin >> n; for(int i=1;i<=n;i++) { cin >> a[i]; sum+=a[i]; } for(int i=1;i<=n;i++) cin >> b[i]; sort(b+1,b+n+1); if(b[n]+b[n-1]>=sum) cout<<"YES"<<endl; else cout<<"NO"<<endl; }
B.维护left
#include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!! ") #define pb push_back #define inf 1e9 //std::ios::sync_with_stdio(false); using namespace std; //priority_queue<int,vector<int>,greater<int>> que; const double EPS = 1.0e-8; const double eps = 1.0e-8; typedef pair<int, int> pairint; typedef long long ll; typedef unsigned long long ull; const int maxn = 3e5 + 10; const int maxm = 300; const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}}; //next_permutation int a[1000005]; int main() { //freopen("in.txt", "r", stdin); int n; cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; } int remain = 0; int left = n+1; for (int i = n; i >= 1; i--) { if (i < left) { remain++; left = i; } left = min(left, max(1, i - a[i])); } cout << remain << endl; }
C.找出搞出1的最少次数
#include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!! ") #define pb push_back #define inf 1e9 //std::ios::sync_with_stdio(false); using namespace std; //priority_queue<int,vector<int>,greater<int>> que; const double EPS = 1.0e-8; const double eps = 1.0e-8; typedef pair<int, int> pairint; typedef long long ll; typedef unsigned long long ull; const int maxn = 3e5 + 10; const int maxm = 300; const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}}; //next_permutation int a[2005]; int b[2005][2005]; int anser = 0; int n; int gcd(int x, int y) { if (y == 0) { return x; } else { return (gcd(y, x % y)); } } void dfs(int x) { int flag = 0; int now = n - x; for (int i = 1; i <= now; i++) { b[x][i] = gcd(b[x - 1][i], a[i + x]); if (b[x][i] == 1) { anser = x; flag = 1; break; } } if (!flag) { dfs(x + 1); } } int main() { //freopen("in.txt", "r", stdin); int flag = 0; int finalgcd; int cur=0; cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; if (a[i] == 1) { cur++; flag = 1; } } if (flag) { cout << n - cur << endl; return 0; } flag = 0; for (int i = 1; i < n; i++) { b[1][i] = gcd(a[i], a[i + 1]); if (i == 1) { finalgcd = b[1][1]; } else { finalgcd = gcd(finalgcd, a[i + 1]); } if (b[1][i] == 1) { flag = 1; break; } } //TS; if (flag) { cout << n << endl; } else { if (finalgcd != 1) { cout << -1 << endl; } else { //TS; dfs(2); cout << anser + n - 1 << endl; } } }
!!!D.构造题 给定一个数组a,将a中的元素调换位置变成b数组,使得对于每一个下标子集,a中对应下标的元素和不等于b中对应下标的元素和.
正解:
把a序列做一个排序,设为c序列,然后我们开始构造b序列
b[i]=c[(j+1)%n],满足c[j]=a[i]
证明:
a) 假设我在a序列中取得子序列不包含最大值的话。那么一定满足a的子序列的和总小于b的子序列的和。
b) 假设我在a序列中取得子序列包含最大值的话。那么只要子序列的长度小于n,就一定会有a的子序列的和总大于b的子序列的和。
综上所述,a、b中挑选对应位置的子序列,只要长度<n,那么和就永远不可能相等
#include <bits/stdc++.h> using namespace std; const int maxn=30; int a[maxn]; int b[maxn]; int n; bool cmp(int a,int b) { return a>b; } int fid(int x) { for(int i=0;i<n;i++){ if(b[i]==x){ return i; } } } int main() { // freopen("data.in","r",stdin); //freopen("data.out","w",stdout); cin>>n; for(int i=0;i<n;i++){ cin>>a[i]; b[i]=a[i]; } sort(b,b+n,cmp); int index; for(int i=0;i<n;i++){ index=fid(a[i]); if(index==0){ cout<<b[n-1]<<" "; } else{ cout<<b[index-1]<<" "; } } cout<<endl; }