11.08练习赛
T1 吃糖
这道题没有什么好说的,从100枚举到2,用\(N^2\)的搜索暴力\(Check\)即可。
然而我打爆了
最后发现是在dfs2里条件判断错误。
我真是个憨憨
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
char *p1,*p2,buf[1<<20];
//#define GC (p1==p2&&(p1=buf,p2=buf+fread(buf,1,1<<20,stdin),p1==p2)?0:(*(p1++)))
#define GC getchar()
#define ri register int
inline int in()
{
int w=0,x=0;
char ch=0;
while(!isdigit(ch)){
w|=ch=='-';
ch=GC;
}
while(isdigit(ch)){
x=(x<<3)+(x<<1)+(ch^48);
ch=GC;
}
return w? -x:x;
}
int r,c;
int a[110][110];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int _max;
int cut=0;
struct point{
int x,y;
};
queue<point>q;
bool vis[110][110];
bool vis1[110][110];
void dfs(int x,int y,int k)
{
vis[x][y]=1;
cut+=1;
int i;
for(i=0;i<4;i++){
int tx=x+dx[i],ty=y+dy[i];
if(vis[tx][ty])continue;
if(tx==0||tx==r+1||ty==0||ty==c+1)continue;
if(a[tx][ty]<k)continue;
dfs(tx,ty,k);
}
return;
}
int dfs1(int x,int y)
{
vis1[x][y]=1;
int i;
int k=1;
for(i=0;i<4;i++){
int tx=x+dx[i],ty=y+dy[i];
if(vis[tx][ty])continue;
if(vis1[tx][ty])continue;
if(tx==0||tx==r+1||ty==0||ty==c+1)continue;
k+=dfs1(tx,ty);
}
return k;
}
bool check(int x)
{
memset(vis,0,sizeof(vis));
memset(vis1,0,sizeof(vis1));
int i,j;
cut=0;
for(i=1;i<=c;i++){
if(a[1][i]>=x)q.push((point){1,i});
if(a[r][i]>=x)q.push((point){r,i});
}
for(i=1;i<=r;i++){
if(a[i][1]>=x)q.push((point){i,1});
if(a[i][c]>=x)q.push((point){i,c});
}
while(q.size()){
int A=q.front().x,B=q.front().y;
q.pop();
if(vis[A][B])continue;
dfs(A,B,x);
}
for(i=1;i<=r;i++)
{
for(j=1;j<=c;j++)
{
if(!vis[i][j]){
int k=dfs1(i,j);
if(k==r*c-cut){
return 0;
}
else return 1;
}
}
}
return 0;
}
bool inf[110];
int main()
{
// freopen("candies.in","r",stdin);
// freopen("candies.out","w",stdout);
r=in();c=in();
ri i,j;
for(i=1;i<=r;i++)
{
for(j=1;j<=c;j++)
{
a[i][j]=in();
inf[a[i][j]]=1;
_max=max(_max,a[i][j]);
}
}
for(i=_max;i>=2;i--)
{
if(check(i)){
printf("%d\n",i);
return 0;
}
}
printf("-1\n");
return 0;
}
T2 卡片
题面是真的长,而且大部分都没用
稍微描述一下题面:
其实就是一个三关键字排序,问最多能选出多少个连续的数集。
听liudl带佬说是三维偏序,于是我打了个二位数点(逃
首先膜一下Qhr带佬,他居然是(本人所知)全小机房唯一一个想出来可以用图论来搞这道题人。而这也是本题的正解(之一)。能拿20那种
(具体做法是把所有\(p_i<p_j\)的点连起来,然后跑最长路)
正解是用一个叫做CDQ分治的东西把三维转换成二维。然而我并不会
还有一个正解就是把20分做法和80分做法整合起来,就能A掉了。
注:在这种小规模的最短/长路中最好用SPFA,又短又好写而且小数据绝对卡不掉。(关于SPFA:他活了)
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
char *p1,*p2,buf[1<<20];
//#define GC (p1==p2&&(p1=buf,p2=buf+fread(buf,1,1<<20,stdin),p1==p2)?0:(*(p1++)))
#define GC getchar()
inline int in() {
int x=0,w=0;
char ch=0;
while(!isdigit(ch)) {
w|=ch=='-';
ch=GC;
}
while(isdigit(ch)) {
x=(x<<3)+(x<<1)+(ch^48);
ch=GC;
}
return w? -x:x;
}
inline int lowbit(int x) {
return x&(-x);
}
const int maxn= 1e6 + 5;
struct node {
int x,y,z;
} g[maxn];
int _max;
int n;
namespace s1 {
bool cmp(node a,node b) {
if(a.x!=b.x)return a.x<b.x;
else return a.y<b.y;
}
int sum[1000010];
void ins(int x,int k) {
for(; x<=maxn; x+=lowbit(x)) {
sum[x]=max(sum[x],k);
if(x==0)break;
}
return;
}
int gs(int x) {
int res=0;
for(;;x-=lowbit(x)) {
res=max(res,sum[x]);
if(x==0)break;
}
return res;
}
void s1() {
sort(g+1,g+n+1,cmp);
int ans=0;
for(int i=1; i<=n; ++i) {
int v=g[i].y;
ins(v,gs(v)+1);
ans=max(ans,gs(v));
}
printf("%d\n",ans);
return;
}
}
namespace s2 {
struct edge {
int to,next;
} e[maxn*2];
int head[maxn],cnt;
void add(int from,int to) {
e[++cnt].next=head[from];
e[cnt].to=to;
head[from]=cnt;
}
int ans=0;
bool inq[maxn];
int dis[maxn];
queue<int>q;
void spfa(int x)
{
for(int i=1;i<=n;i++)dis[i]=inq[i]=0;
q.push(x);
inq[x]=1;
while(q.size()){
int u=q.front();
q.pop();
inq[u]=0;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(dis[u]+1>dis[v]){
dis[v]=dis[u]+1;
if(!inq[v]){
q.push(v);
inq[v]=1;
}
}
}
}
}
void s2() {
int i,j;
for(i=1; i<=n; i++) {
for(j=1; j<=n; j++) {
if(i==j)continue;
if(g[i].x<=g[j].x&&g[i].y<=g[j].y&&g[i].z<=g[j].z){
add(i,j);
}
}
}
for(i=1; i<=n; i++) {
spfa(i);
for(j=1;j<=n;j++)
{
ans=max(ans,dis[j]+1);
}
}
printf("%d\n",ans);
return;
}
}
int main() {
bool if0=1;
n=in();
for(int i=1; i<=n; ++i) {
g[i].x=in();
g[i].y=in();
g[i].z=in();
if(g[i].z!=0)if0=0;
_max=max(g[i].y,_max);
}
if(if0) {
s1::s1();
return 0;
} else {
s2::s2();
return 0;
}
}
这次想装一下B所以用了用namespace,好孩子不要学
原文地址:https://www.cnblogs.com/cooper233/p/11828758.html
时间: 2024-10-12 20:03:06