跟着付队一起打的第二场gym,差点就被付队爆0了,还好趁他不注意切了两个水题(付队tql)
C.Evolution Game
题意:有n个不同版本的野兽,定义属性:第 i 个野兽有 i 个眼睛和 h[i] 个角,你可以任意从中选择一个野兽进行进化,每次进化角数量必须增加,而且进化后假设有a 个眼睛 b个角,假设h[i]=b,那么abs(a-i)<=w,否则不能进化,求最多的进化次数。
思路:从大到小枚举h[i]的值,设d[i]为从第 i 个野兽开始进化所能得到的答案,如果对于 j,h[j]
#include
#define ll long long
using namespace std;
const int maxn=5005,inf=1e9;
int d[maxn],h[maxn];
int main()
{
int n,w,p=0,ans=0;
scanf("%d%d",&n,&w);
for(int i=1;i<=n;i++)
{
scanf("%d",&h[i]);
if(h[i]>h[p])p=i;
}
int m=n;
while(m--)
{
for(int i=1;i<=n;i++)
if(h[i]h[p])p=i;
}
printf("%d\n",ans);
}
D. Bus Stop
题意:有n个房子的坐标,你要建立公交车站,使得每个房子离最近的车站不过10公里,求最少的车站。
思路:直接贪心,从左往右遍历房子,如果一个房子没被覆盖,就在他右边10公里建车站即可。
#include
#define ll long long
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,x,p=-100,ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
if(x>p+10)
ans++,p=x+10;
}
printf("%d\n",ans);
}
}
G. Communication
题意:给一些有向边,如果两个点可以互达,那么这两个点属于同一组,求你给有向图分组。
思路:就是强连通裸题。
#include
#define ll long long
using namespace std;
const int maxn=205;
vectorG[maxn];
int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;
stackS;
void dfs(int u)
{
pre[u]=lowlink[u]=++dfs_clock;
S.push(u);
for(int i=0;i
K. The Stream of Corning 2
付队写的,我还有事先溜了,贴付队线段树代码:
#include
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=400010;
struct in{
int opt,t,val,id;
in(){}
in(int oo,int tt,int vv):opt(oo),t(tt),val(vv){}
friend bool operator <(in w,in v){
if(w.t^v.t) return w.t>1;
if(pos<=Mid) add(Now<<1,L,Mid,pos,val);
else add(Now<<1|1,Mid+1,R,pos,val);
}
int query(int Now,int L,int R,int K)
{
if(L==R) return L; int Mid=(L+R)>>1;
if(sum[Now<<1]>=K) return query(Now<<1,L,Mid,K);
return query(Now<<1|1,Mid+1,R,K-sum[Now<<1]);
}
int main()
{
int C=0,T,N,M,Mx,op,x,y,z;
scanf("%d",&T);
while(T--){
scanf("%d",&N); tot=0; cnt=0;
rep(i,1,N){
scanf("%d%d%d",&op,&x,&y);
if(op==1) {
scanf("%d",&z);
s[++cnt]=in(1,x,y);
s[++cnt]=in(3,z,y);
b[++tot]=y;
}
else s[++cnt]=in(2,x,y);
s[cnt].id=i;
ans[i]=0;
}
sort(b+1,b+tot+1);
tot=unique(b+1,b+tot+1)-(b+1);
sort(s+1,s+cnt+1);
rep(i,1,tot<<1) sum[i]=0;
rep(i,1,cnt){
//cout<
L. Largest Allowed Area
题意:求一个最大的子矩阵,子矩阵的和要么为0要么为1。
贴付队单调队列代码(明天回来补完):
#include
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1010;
char c[maxn][maxn];
int ans[maxn][maxn],sum[maxn][maxn];
int main()
{
int T,N,M,Mx;
scanf("%d",&T);
while(T--){
scanf("%d%d",&N,&M); Mx=0;
rep(i,1,N)
rep(j,1,M){
c[i][j]=getchar();
while(c[i][j]!='0'&&c[i][j]!='1') c[i][j]=getchar();
//scanf("%d",&c[i][j]),
sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+(c[i][j]=='1');
}
rep(i,1,N)
rep(j,1,M){
ans[i][j]=ans[i-1][j-1]-1;
if(ans[i][j]<1) ans[i][j]=1;
while(i+ans[i][j]<=N&&j+ans[i][j]<=M&&(sum[i+ans[i][j]][j+ans[i][j]]-sum[i-1][j+ans[i][j]]-sum[i+ans[i][j]][j-1]+sum[i-1][j-1]<=1)) ans[i][j]++;
Mx=max(Mx,ans[i][j]);
}
printf("%d\n",Mx);
}
return 0;
}