题意 给你两个小长方形 然后他们的最左边是对准一条线的 问你旁边宽度为1范围内有多少包围的格子
我们不难发现一个长方形的贡献 是 (h+1)*2 + w 但是如果一个的w比另一个w高 我们就需要加上abs(w1-w2)的贡献即可
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
int main()
{
//ios::sync_with_stdio(false);
//freopen("a.txt","r",stdin);
//freopen("b.txt","w",stdout);
long long a,b,c,d;
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
long long ans = (d+1)*2+c+(b+1)*2+a+abs(a-c);
printf("%lld\n",ans);
//fclose(stdin);
//fclose(stdout);
//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
return 0;
}
这题题意 是给你n个足球场上时刻的比分 问你在这一场比赛中 有多少次可能双方同分的情况
做法 我们知道只要在上一个和现在去枚举 之间两队都有一个比分范围 只要有交集就是贡献 但是要特判掉有些重复的影响
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
const int MAX_N = 10025;
struct node
{
int l,r;
}arr[MAX_N];
int main()
{
//ios::sync_with_stdio(false);
//freopen("a.txt","r",stdin);
//freopen("b.txt","w",stdout);
int n;
long long ans = 0;
scanf("%d",&n);
for(int i = 1;i<=n;++i)
{
scanf("%d%d",&arr[i].l,&arr[i].r);
}
arr[0].l = 0,arr[0].r = 0;
int st = 1;
while(arr[st].l==0&&arr[st].r==0) ans = 1,st++;
//dbg(ans);
for(int i = st;i<=n;++i)
{
while(arr[i].l==arr[i-1].l&&arr[i].r==arr[i-1].r) i++;
if(i>n) break;
long long tmp = max(arr[i-1].l,arr[i-1].r);
long long tmp_ = min(arr[i].l,arr[i].r);
if(tmp_<tmp) continue;
ans+= tmp_-tmp+1;
//dbg3(i,tmp_,tmp);
if(arr[i-1].l==arr[i-1].r&&i!=1) ans--;
//dbg(ans);
}
printf("%lld\n",ans);
//fclose(stdin);
//fclose(stdout);
//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
return 0;
}
题意 给你n个数值 让你产生一种答案序列使得相邻两个的差的最大值最小 n和1也算相邻
做法 我们按照1到中间递增 从中间到n递减的顺序插入数组即可 一次插两个 一左一右
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
const int MAX_N = 125;
int arr[MAX_N],ans[MAX_N];
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
//ios::sync_with_stdio(false);
//freopen("a.txt","r",stdin);
//freopen("b.txt","w",stdout);
int n;
scanf("%d",&n);
for(int i = 1;i<=n;++i) scanf("%d",&arr[i]);
sort(arr+1,arr+1+n,cmp);
if(n%2==0)
{
int tmp = n/2;
ans[tmp] = arr[1],ans[tmp+1] = arr[2];
for(int i = 1;i<=n/2;++i)
ans[tmp-i] = arr[2*i+1],ans[tmp+1+i] = arr[2*(i+1)];
}
else
{
int tmp = n/2+1;
ans[tmp] = arr[1];
for(int i = 1;i<=n/2;i++)
{
ans[tmp-i] = arr[2*i];
ans[tmp+i] = arr[2*i+1];
}
}
for(int i = 1;i<=n;++i)
i==n?printf("%d\n",ans[i]):printf("%d ",ans[i]);
//fclose(stdin);
//fclose(stdout);
//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
return 0;
}
题意 给你一个n*m的矩阵 矩阵i j的意思是 ‘>’表示 第i道菜比第j道菜好吃 =是相等 那么我们知道先用并查集把等于的都处理以后 你再用拓扑写 因为等级越高的数越大 那么你应该让等级高的入度加加 这样他最后一个出现 然后队列中答案的贡献 就是 ans[x] = max(ans[pre]+1,ans[x]);
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
const int MAX_N = 1025;
char str[MAX_N][MAX_N];
bool vis[MAX_N<<1];
int indegre[MAX_N<<1],p[MAX_N<<1],eid,res,tmp,n,m,ans[MAX_N<<1],fa[MAX_N<<1];
struct edge
{
int v,next;
}e[MAX_N*MAX_N];
void add(int u,int v)
{
e[eid].v = v;
e[eid].next = p[u];
p[u] = eid++;
}
void init()
{
memset(p,-1,sizeof(p));
eid = 0;
}
int Find(int x)
{
if(fa[x] == x) return x;
return fa[x] = Find(fa[x]);
}
void Merge(int x,int y)
{
x = Find(x), y = Find(y);
if(x!=y)
{
res++;
fa[x] = y;
}
}
void tops()
{
queue<int > q;
for(int i = 1;i<=n+m;++i)
{
int x = Find(i);
if(!indegre[x]&&!vis[x])
{
ans[x] = 1;
q.push(x);
tmp++;
vis[x] = true;
}
}
while(!q.empty())
{
int pre = q.front();
q.pop();
for(int i = p[pre];i+1;i=e[i].next)
{
int to = Find(e[i].v);
indegre[to]--;
ans[to] = max(ans[pre]+1,ans[to]);
if(!indegre[to]&&!vis[to])
{
vis[to] = true;
tmp++;
q.push(to);
}
}
}
}
int main()
{
//ios::sync_with_stdio(false);
//freopen("a.txt","r",stdin);
//freopen("b.txt","w",stdout);
scanf("%d%d",&n,&m);
init();
for(int i = 1;i<=n+m;++i) fa[i] = i;
for(int i = 1;i<=n;++i)
{
scanf("%s",str[i]+1);
for(int j = 1;j<=m;++j)
{
if(str[i][j]=='=') Merge(i,j+n);
}
}
for(int i = 1;i<=n;++i)
{
for(int j = 1;j<=m;++j)
{
if(str[i][j]=='<')
{
add(Find(i),Find(j+n));
indegre[Find(j+n)]++;
}
else if(str[i][j]=='>')
{
add(Find(j+n),Find(i));
indegre[Find(i)]++;
}
}
}
tops();
if(n+m!=res+tmp)
{
printf("No\n");
return 0;
}
printf("Yes\n");
for(int i = 1;i<=n;++i)
{
int x = Find(i);
i==n?printf("%d\n",ans[x]):printf("%d ",ans[x]);
}
for(int i = 1;i<=m;++i)
{
int x = Find(i+n);
i==m?printf("%d\n",ans[x]):printf("%d ",ans[x]);
}
//fclose(stdin);
//fclose(stdout);
//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
return 0;
}
题意 按照一种方式生成字符串 问你最后生成的串中最长连续单个字符长度是多少
做法 我们只要枚举 a - z 贪心的去考虑整个过程 你答案最大值一定是一开始就最大值取过来去构造
所以我们以a为例 如果你输入的全是a 那么我之前最大是tmp 能插入tmp+1个地方 贡献就是 (tmp+1)*str[j].size()
那么新tmp += (tmp+1)*str[j].size() 即可
但是万一不全是a 你可以从str[j]中取最多连续a 或者等于 1 + str[j]前面一段连续a 和str[j]后面一段连续a
枚举即可
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
const int MAX_N = 100025;
string str[MAX_N];
bool check(char ch,int i)
{
int sz = str[i].size();
for(int j = 0;j<sz;++j)
{
if(str[i][j]!=ch) return false;
}
return true;
}
int cal(char ch,int i)
{
int maxx = 0,res = 0,sz = str[i].size();
for(int j = 0;j<sz;++j)
{
if(str[i][j]==ch) res++;
else maxx = max(maxx,res),res = 0;
}
maxx = max(maxx,res);
return maxx;
}
int Front(char ch,int i)
{
int res = 0,sz = str[i].size();
for(int j = 0;j<sz;++j)
{
if(str[i][j]==ch) res++;
else return res;
}
}
int Back(char ch,int i)
{
int res = 0,sz = str[i].size();
for(int j = sz-1;j>=0;j--)
{
if(str[i][j]==ch) res++;
else return res;
}
}
int main()
{
//ios::sync_with_stdio(false);
//freopen("a.txt","r",stdin);
//freopen("b.txt","w",stdout);
int n;
long long ans = 0;
scanf("%d",&n);
for(int i = 1;i<=n;++i) cin >>str[i];
for(int i = 0;i<26;++i)
{
ll tmp = 0;
for(int j = 1;j<=n;++j)
{
if(tmp==0)
{
tmp = cal('a'+i,j);
}
else
{
int len = str[j].size();
if(check('a'+i,j))
{
tmp = tmp + (tmp+1)*len;
}
else
{
tmp = max(1+Back('a'+i,j)+Front('a'+i,j),cal('a'+i,j));
}
}
}
ans = max(ans,tmp);
}
cout <<ans << endl;
//fclose(stdin);
//fclose(stdout);
//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
return 0;
}
题意 给你几种加边方式 让你输出原先序列
我们用并查集建树 就是把两个操作合并在一起 然后从树根开始往下输出答案即可
样例的树是长这样的
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
const int MAX_N = 300025;
int fa[MAX_N],n;
int p[MAX_N],eid;
void init()
{
eid = 0;
memset(p,-1,sizeof(p));
}
struct edge
{
int v,next;
}e[MAX_N<<2];
void add(int u,int v)
{
e[eid].v = v;
e[eid].next = p[u];
p[u] = eid++;
}
int Find(int x)
{
if(fa[x] == x) return x;
return fa[x] = Find(fa[x]);
}
void dfs(int x)
{
if(x<=n) printf("%d ",x);
for(int i = p[x];i!=-1;i=e[i].next)
{
int to = e[i].v;
dfs(to);
}
}
int main()
{
//ios::sync_with_stdio(false);
//freopen("a.txt","r",stdin);
//freopen("b.txt","w",stdout);
init();
int a,b;
for(int i = 1;i<=MAX_N - 2;++i) fa[i] = i;
scanf("%d",&n);
int cnt = n;
for(int i = 1;i<n;++i)
{
scanf("%d%d",&a,&b);
int x = Find(a),y = Find(b);
cnt++;
fa[x] = cnt,fa[y] = cnt;
add(cnt,x),add(cnt,y);
}
dfs(cnt);
//fclose(stdin);
//fclose(stdout);
//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
return 0;
}