A Yet Another Dividing into Teams
题意:n个不同的数,要对n个数进行分组,要求每组里面的任意差值的绝对值不能为1.
为你组数.
思路:很明显最多2组,找里面是否有2个差绝对值为1的,如果有就为2,没有就为 1.
代码
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 2e5+10;
template<typename T>T gcd(T a, T b) {return b==0?a:gcd(b, a%b);}
template<typename T>T exgcd(T a,T b,T &g,T &x,T &y){if(!b){g = a,x = 1,y = 0;}else {exgcd(b,a%b,g,y,x);y -= x*(a/b);}}
#ifndef ONLINE_JUDGE
#define debug(fmt, ...) {printf("debug ");printf(fmt,##__VA_ARGS__);puts("");}
#else
#define debug(fmt, ...)
#endif
typedef long long ll;
const ll mod = 1e9+7;
int a[110];
int vis[man];
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt","w",stdout);
#endif
int t;
cin >> t;
while(t--){
int n;scanf("%d",&n);
for(int i = 1;i <= n;i++){
cin >> a[i];
}
sort(a+1,a+1+n);
int ans = 0;
for(int i = 1;i <= n-1;i++){
if(a[i]==a[i+1]-1){
ans++;
break;
}
}
if(!ans)printf("1\n");
else printf("2\n");
}
return 0;
}
B2 - Books Exchange (hard version)
题意:略。
思路:①因为肯定是形成一个环的,所以并查集并一下就好了。
②记忆化搜索。
代码
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 3e5+10;
template<typename T>T gcd(T a, T b) {return b==0?a:gcd(b, a%b);}
template<typename T>T exgcd(T a,T b,T &g,T &x,T &y){if(!b){g = a,x = 1,y = 0;}else {exgcd(b,a%b,g,y,x);y -= x*(a/b);}}
#ifndef ONLINE_JUDGE
#define debug(fmt, ...) {printf("debug ");printf(fmt,##__VA_ARGS__);puts("");}
#else
#define debug(fmt, ...)
#endif
typedef long long ll;
const ll mod = 1e9+7;
int a[man];int n;
int dp[man],vis[man];
int dfs(int i,int cnt){
if(dp[i])return dp[i];
if(i==a[i]||vis[i]==1)return 0;
vis[i] = 1;
cnt++;
dp[i] = dfs(a[i],cnt) + cnt;
//cout << dp[i] << " " << i << endl;
vis[i] = 0;
cnt--;
return dp[i] - cnt;
}
int main() {
#ifndef ONLINE_JUDGE
//freopen("in.txt", "r", stdin);
//freopen("out.txt","w",stdout);
#endif
int t;
cin >> t;
while(t--){
cin >> n;
for(int i = 1;i <= n;i++){
cin >> a[i];
// cout << a[i] <<endl;
}
memset(dp,0,sizeof(dp));
memset(vis,0,sizeof(vis));
for(int i = 1;i <= n;i++){
if(a[i]==i)cout << 1 << " ";
else cout << dfs(i,0) << " ";
}cout << endl;
}
return 0;
}
C2. Good Numbers (hard version)
题意:
好数:有3的幂组成的和,幂相同的都出现一次。
给你一个n,找比n第一个大的好数。
思路:
考虑三进制,如果这个数位好数,肯定三进制上都是0 ,1
如果有2肯定不是好数,那么离这个数最近的好数是多少。
我们肯定要让最后一个2进位变成0,而最后一个2的进位会对之后的进位也会有影响,所有我们找最后一个2之后出现的第一个0的位置,然后0位置之前的数全为0,这位为1,在转换一下就好了。
代码
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 2e5+10;
template<typename T>T gcd(T a, T b) {return b==0?a:gcd(b, a%b);}
template<typename T>T exgcd(T a,T b,T &g,T &x,T &y){if(!b){g = a,x = 1,y = 0;}else {exgcd(b,a%b,g,y,x);y -= x*(a/b);}}
#ifndef ONLINE_JUDGE
#define debug(fmt, ...) {printf("debug ");printf(fmt,##__VA_ARGS__);puts("");}
#else
#define debug(fmt, ...)
#endif
typedef long long ll;
const ll mod = 1e9+7;
ll a[50];
int cnt = 0;
void add(){
a[0] = 1;
for(int i = 1;i <= 38;i++){
a[i] = a[i-1]*3;
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt","w",stdout);
#endif
int t;
// init();
cin >> t;
while(t--){
ll n;
cin >> n;
vector<int>sp;
int pos = -1;
while(n){
sp.push_back(n%3);
if(sp.back()==2)pos = (int)sp.size()- 1;
n /= 3;
}
sp.push_back(0);
ll tp = 1;
if(pos!=-1){
int id = find(sp.begin() + pos ,sp.end(),0) - sp.begin();
for(int i = id - 1;i >= 0;i--){
sp[i] = 0;
}
sp[id] = 1;
}
ll ans = 0;
//cout << cnt << endl;
for(int i = 0;i < sp.size();i++){
ans += 1ll*tp*sp[i];
tp *= 3;
}
cout << ans << endl;
}
return 0;
}
D2 - Too Many Segments (hard version)
题意:略;
思路:考虑对于当前l来说,如果当前l不满足,需要减,则我们就减掉r最远的那个区间,因为这不仅减少了当前的影响,还更大的减少对之后的影响。
代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 2e5+10;
template<typename T>T gcd(T a, T b) {return b==0?a:gcd(b, a%b);}
template<typename T>T exgcd(T a,T b,T &g,T &x,T &y){if(!b){g = a,x = 1,y = 0;}else {exgcd(b,a%b,g,y,x);y -= x*(a/b);}}
#ifndef ONLINE_JUDGE
#define debug(fmt, ...) {printf("debug ");printf(fmt,##__VA_ARGS__);puts("");}
#else
#define debug(fmt, ...)
#endif
typedef long long ll;
const ll mod = 1e9+7;
struct node{
int l,r,id;
bool operator <(const node &a)const{
return r < a.r;
}
};
vector<node >sp(man);
priority_queue<node>s;
int vis[man];
bool cmp(node &a,node &b){
return a.l < b.l;
}
int main() {
#ifndef ONLINE_JUDGE
//freopen("in.txt", "r", stdin);
//freopen("out.txt","w",stdout);
#endif
int n,k;
cin >> n >> k;
for(int i = 1;i <= n;i++){
int l,r;cin >> l >> r;
sp.push_back(node{l,r,i});
vis[l]++;
vis[r+1]--;
}
sort(sp.begin(),sp.end(),cmp);
int sum = 0,ans = 0,id = 0;
vector<int>res;
for(int i = 1;i <= man-5;i++){
sum += vis[i];
if(sum<=k)continue;
while(id < sp.size()&&sp[id].l <= i){
s.push(sp[id]);
id++;
}
while(sum>k){
node tp = s.top();s.pop();
sum--;
ans++;
vis[tp.r+1]++;
res.push_back(tp.id);
}
}
cout << ans << endl;
for(int i = 0;i < res.size();i++){
cout << res[i] << " ";
}cout <<endl;
return 0;
}
E - By Elevator or Stairs?
题意:略
思路:一个简单dp,dp[i][0]表示当前第i层选择楼梯的前i层最小的值。
dp[i][1]表示当前i层选择电梯的前i层的最小值
转移:
dp[i][0] = min(dp[i-1][0],dp[i-1][1]) + a[i];
dp[i][1] = min(dp[i-1][0] + k,dp[i-1][1]) + b[i];
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 2e5+10;
template<typename T>T gcd(T a, T b) {return b==0?a:gcd(b, a%b);}
template<typename T>T exgcd(T a,T b,T &g,T &x,T &y){if(!b){g = a,x = 1,y = 0;}else {exgcd(b,a%b,g,y,x);y -= x*(a/b);}}
#ifndef ONLINE_JUDGE
#define debug(fmt, ...) {printf("debug ");printf(fmt,##__VA_ARGS__);puts("");}
#else
#define debug(fmt, ...)
#endif
typedef long long ll;
const ll mod = 1e9+7;
int a[man],b[man];
int dp[man][2];
int main() {
#ifndef ONLINE_JUDGE
//freopen("in.txt", "r", stdin);
//freopen("out.txt","w",stdout);
#endif
int n,k;
cin >> n >> k;
for(int i = 2;i <= n;i++)cin >> a[i];
for(int i = 2;i <= n;i++)cin >> b[i];
dp[2][0] = a[2];
dp[2][1] = b[2] + k;
for(int i = 3;i <= n;i++){
dp[i][0] = min(dp[i-1][0],dp[i-1][1])+a[i];
dp[i][1] = min(dp[i-1][0] + k ,dp[i-1][1]) + b[i];
}
for(int i = 1;i <= n;i++){
cout << min(dp[i][1],dp[i][0]) << " ";
}cout <<endl;
return 0;
}
F:待补