A - Rooms and Passages
题意:找到每个数后面第一个负正对。
从前往后比较麻烦。从后向前,先记录正数位置,一旦出现这个数的相反数即产生一对负正对,通过和前面的负正对比较更新答案。
view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define endl '
'
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
const int maxn = 5e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
ll Map[maxn];
ll ans[maxn];
ll a[maxn];
int main()
{
ll n = read();
rep(i,1,n) a[i] = read();
int pre = inf;
per(i,n,1)
{
if(a[i]>0)
{
if(pre==inf) Map[a[i]] = i,ans[i] = n-i+1;
else
{
ans[i] = pre - i;
Map[a[i]] = i;
}
}
else
{
if(!Map[-a[i]])
{
ans[i] = min(pre - i,n - i + 1);
}
else
{
ans[i] = min(Map[-a[i]] - i,pre-i);
pre = min(pre,Map[-a[i]]);
}
}
}
rep(i,1,n) cout<<ans[i]<<' ';cout<<endl;
return 0;
}
B - Rearrange Columns
题意:给你一个(2*n)矩阵,只含有#和. , 问你在可以交换任意列的情况下能否使得#联通。
思路:列只有四种情况
1 #和.
2 .和#
3 #和#
4 .和.
只有在3不存在且12同时存在的时候才会NO。
其他情况下就3放中间其他放两边即可。
view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define endl '
'
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
vector<ll> fi_type;
vector<ll> se_type;
vector<ll> th_type;
vector<ll> es_type;
int main()
{
char s[3][5000];
char ans[3][5000];
gets(s[1]+1);
gets(s[2]+1);
int len = strlen(s[1]+1);
rep(j,1,len)
{
if(s[1][j]=='#'&&s[2][j]=='#') fi_type.pb(j);
else if(s[1][j]=='#'&&s[2][j]=='.') se_type.pb(j);
else if(s[1][j]=='.'&&s[2][j]=='#') th_type.pb(j);
else es_type.pb(j);
}
if(fi_type.size()==0&&se_type.size()&&th_type.size())
{
cout<<"NO"<<endl;
}
else
{
cout<<"YES"<<endl;
per(j,len,1)
{
if(th_type.size())
{
int cur = th_type[th_type.size()-1];
ans[1][j] = s[1][cur], ans[2][j] = s[2][cur];
th_type.pop_back();
}
else if(fi_type.size())
{
int cur = fi_type[fi_type.size()-1];
ans[1][j] = s[1][cur], ans[2][j] = s[2][cur];
fi_type.pop_back();
}
else if(se_type.size())
{
int cur = se_type[se_type.size()-1];
ans[1][j] = s[1][cur], ans[2][j] = s[2][cur];
se_type.pop_back();
}
else
{
int cur = es_type[es_type.size()-1];
ans[1][j] = s[1][cur], ans[2][j] = s[2][cur];
es_type.pop_back();
}
}
rep(i,1,2) rep(j,1,len)
{
cout<<ans[i][j];
if(j==len) cout<<endl;
}
}
return 0;
}
C - Jumps on a Circle
题意:给你一个大小为p,编号从(0~p-1)的环,从0开始往前跳,步长从1开始每次增1,问跳了n次后有多少个格子被踩到过。
思路:当前的位置即是
pos = ({{n(n-1)}over 2}) (\%p)。
当n = 2p时 pos = 0,
当n = 2p+1时, pos = (p(p-1)+2p + 1)%p = 1。
即发现2p为一个循环节。所以总的遍历次数不超过2p,O(2p)遍历一遍就可以了。
view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define endl '
'
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 1e7+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
ll vis[maxn];
int main()
{
ll p = read(), n = read();
n = min(n,2*p+1);
ll cur = 0;
vis[0] = 1;
ll step = 1;
ll ans = 1;
while(n--)
{
cur += step;
cur %= p;
if(!vis[cur]) ans ++;
vis[cur] = 1;
step ++;
}
cout<<ans<<endl;
return 0;
}
J - The Power of the Dark Side - 2
题意:有n个人,每个人有三个属性,如果这个人有两个属性比其他某个人的这两个属性都高,就能打败他。现在可以在攻击的时候调整自身属性,重新分配技能点,问每个人最多能打败多少人。
思路:贪心。肯定是先分配一个0打对方的最高的,自己剩下来的平分给自己两个属性来打对面。所以只用看自己的三者和-2(至少比对方最小两个都大1)能否大于等于对方的两个最小的和,外层遍历n个人,内层二分即可。
view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define endl '
'
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
const int maxn = 5e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
typedef struct Information
{
ll sum2;
ll sum3;
ll id;
Information(){}
Information(ll a, ll b): sum2(a), sum3(b){}
bool operator< (const Information& a)
{
if(sum2!=a.sum2)
return sum2 < a.sum2;
return sum3 < a.sum3;
}
}I;
I a[maxn];
ll Ans[maxn];
ll Map[maxn];
int main()
{
ll n = read();
rep(i,1,n)
{
ll b[5];
b[1] = read(), b[2] = read(), b[3] = read();
sort(b+1,b+1+3);
a[i].sum2 = b[1] + b[2];
a[i].sum3 = b[1] + b[2] + b[3];
a[i].id = i;
}
sort(a+1,a+1+n);
ll ans = 0;
a[n+1].sum2 = 1e15;
rep(i,1,n)
{
int idx = lower_bound(a+1,a+1+n,Information(a[i].sum3-2,1e15)) - a;
if(idx==i) idx--;
else if(a[idx].sum2==a[i].sum3-2) ;
else
{
if(a[i].sum2>=a[idx].sum2)
idx --;
else idx -= 2;
}
Ans[a[i].id] = idx;
}
rep(i,1,n) cout<<Ans[i]<<' ';
cout<<endl;
//cout<<ans<<endl;
return 0;
}