自家OJ搏杀我

贡献一个全T零分代码

#include<bits/stdc++.h>
using namespace std;
#define rt register int  
int T;
struct number{
	int up1,down1,up2,down2,up3,down3;
}now,res,ans;
int anss;
struct answer{
	int h,m,s;
}answers[1000];
inline int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}

int main()
{
	scanf("%d",&T);
	while(T--){
		scanf("%d/%d %d/%d %d/%d",&now.up1,&now.down1,&now.up2,&now.down2,&now.up3,&now.down3);
		anss=0;//最终方案数 
		res.up1=res.up2=res.up3=0;
		res.down1=res.down2=res.down3=1;
		for(rt i=0;i<=11;++i)
			for(rt j=0;j<=59;++j)
				for(rt k=0;k<=59;++k)
				{
					//时针的度数i*30+j/2+k/120
					//分针的度数j*6+k/10
					//秒针的度数k*6
					res.up1=res.up2=res.up3=0;
					res.down1=res.down2=res.down3=1;
					res.up1=res.up1*120+res.down1*(i*3600+60*j+k);
					res.down1=res.down1*120;
					int g=gcd(res.up1,res.down1);
					res.up1/=g;res.down1/=g;
					
					res.up2=res.up2*10+res.down2*(60*j+k);
					res.down2=res.down2*10;
					g=gcd(res.up2,res.down2);
					res.up2/=g;res.down2/=g;
					
					res.up3=res.up3+res.down3*(6*k);
					g=gcd(res.up3,res.down3);
					res.up3/=g;res.down3/=g; 
					if(res.up1*res.down2>=res.down1*res.up2)
					{
						ans.up1=res.up1*res.down2-res.down1*res.up2;
						ans.down1=res.down1*res.down2;
						g=gcd(ans.up1,ans.down1);
						ans.up1/=g;ans.down1/=g;
					}else{
						ans.up1=res.down1*res.up2-res.up1*res.down2;
						ans.down1=res.down1*res.down2;
						g=gcd(ans.up1,ans.down1);
						ans.up1/=g;ans.down1/=g;
					} 
					if(res.up1*res.down3>=res.down1*res.up3)
					{
						ans.up2=res.up1*res.down3-res.down1*res.up3;
						ans.down2=res.down1*res.down3;
						g=gcd(ans.up2,ans.down2);
						ans.up2/=g;ans.down2/=g;
					}else{
						ans.up2=res.down1*res.up3-res.up1*res.down3;
						ans.down2=res.down1*res.down3;
						g=gcd(ans.up2,ans.down2);
						ans.up2/=g;ans.down2/=g;
					}
					if(res.up2*res.down3>=res.down2*res.up3)
					{
						ans.up3=res.up2*res.down3-res.down2*res.up3;
						ans.down3=res.down2*res.down3;
						g=gcd(ans.up3,ans.down3);
						ans.up3/=g;ans.down3/=g;
					}else{
						ans.up3=res.down2*res.up3-res.up2*res.down3;
						ans.down3=res.down2*res.down3;
						g=gcd(ans.up3,ans.down3);
						ans.up3/=g;ans.down3/=g;
					}
					if((ans.up1==now.up1||ans.up1+now.up1==360*ans.down1)&&ans.down1==now.down1&&
					   (ans.up2==now.up2||ans.up2+now.up2==360*ans.down2)&&ans.down2==now.down2&&
					   (ans.up3==now.up3||ans.up3+now.up3==360*ans.down3)&&ans.down3==now.down3
					){
						answers[++anss].h=i;answers[anss].m=j;answers[anss].s=k;
					}
					
				}
		printf("%d\n",anss);
		for(rt i=1;i<=anss;++i){
			if(answers[i].h<10)printf("0%d:",answers[i].h);
			else printf("%d:",answers[i].h);
			
			if(answers[i].m<10)printf("0%d:",answers[i].m);
			else printf("%d:",answers[i].m);
			
			if(answers[i].s<10)printf("0%d\n",answers[i].s);
			else printf("%d\n",answers[i].s);
		}	
	}
	return 0;
}

预处理!!!

#include<bits/stdc++.h>
using namespace std;
#define x1 X1
#define x2 X2
#define x3 X3
#define y1 Y1
#define y2 Y2
#define y3 Y3
#define rt register int  
int T,ress,gfm;
struct number{
	int up1,down1,up2,down2,up3,down3;
}now,res[15][65][65],ans;
int anss;
struct answer{
	int h,m,s;
}answers[1000];
inline int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}
int x1,y1,x2,y2,x3,y3;
inline void update(int a1,int b1,int a2,int b2,int i,int j,int k)
{
	ress=abs(a1*b2-b1*a2);
	gfm=b1*b2;
	int g=gcd(ress,gfm);
	ress/=g;gfm/=g;
	return;
}
int main()
{
//	freopen("1.in","r",stdin);
//	freopen("1.out","w",stdout); 
	scanf("%d",&T);
	for(rt i=0;i<=11;++i)
			for(rt j=0;j<=59;++j)
				for(rt k=0;k<=59;++k)
				{
					x1=x2=x3=0;y1=y2=y3=1;
					x1=i*3600+60*j+k;y1=120;x2=j*60+k;y2=10;x3=k*6;
					update(x1,y1,x2,y2,i,j,k);res[i][j][k].up1=ress;res[i][j][k].down1=gfm;
					update(x1,y1,x3,y3,i,j,k);res[i][j][k].up2=ress;res[i][j][k].down2=gfm;
					update(x2,y2,x3,y3,i,j,k);res[i][j][k].up3=ress;res[i][j][k].down3=gfm;
				}
	while(T--){
		scanf("%d/%d %d/%d %d/%d",&now.up1,&now.down1,&now.up2,&now.down2,&now.up3,&now.down3);
		anss=0;//最终方案数 
		for(rt i=0;i<=11;++i)
			for(rt j=0;j<=59;++j)
				for(rt k=0;k<=59;++k)
				{
					if((res[i][j][k].up1==now.up1||res[i][j][k].up1+now.up1==360*res[i][j][k].down1)&&res[i][j][k].down1==now.down1&&
					   (res[i][j][k].up2==now.up2||res[i][j][k].up2+now.up2==360*res[i][j][k].down2)&&res[i][j][k].down2==now.down2&&
					   (res[i][j][k].up3==now.up3||res[i][j][k].up3+now.up3==360*res[i][j][k].down3)&&res[i][j][k].down3==now.down3
					){
						answers[++anss].h=i;answers[anss].m=j;answers[anss].s=k;
					}	
				}
		printf("%d\n",anss);
		for(rt i=1;i<=anss;++i){
			if(answers[i].h<10)printf("0%d:",answers[i].h);
			else printf("%d:",answers[i].h);
			if(answers[i].m<10)printf("0%d:",answers[i].m);
			else printf("%d:",answers[i].m);
			if(answers[i].s<10)printf("0%d\n",answers[i].s);
			else printf("%d\n",answers[i].s);
		}	
	}
	return 0;
}

如果求的是确认的两点间的距离,深搜加上连通性预处理可以优化很多时间

#include<bits/stdc++.h>
using namespace std;
#define rt register int 
int n,m,k,A,B;
struct edges{
	int to,nxt,w;
}edge1[50000],edge2[50000];
bool st[1005];
int h1[1005],cnt1,cnt2,h2[1005];
long long dist,ans=0x3f3f3f3f;
inline void add1(int u,int v,int w){edge1[++cnt1].to=v;edge1[cnt1].nxt=h1[u];edge1[cnt1].w=w;h1[u]=cnt1;}
inline void add2(int u,int v,int w){edge2[++cnt2].to=v;edge2[cnt2].nxt=h2[u];edge2[cnt2].w=w;h2[u]=cnt2;}
inline void dfs1(int u,long long dist)
{
	if(dist>ans)return;
	if(u==B){
		if(dist%k==0&&dist<ans){
			ans=dist;return;
		}else return;
	}
	for(rt i=h1[u];i;i=edge1[i].nxt)
	{
		int v=edge1[i].to;
		if(!st[v])continue;
		dist=dist+edge1[i].w;
		dfs1(v,dist);
		dist-=edge1[i].w;
	}
}
inline void dfs2(int u)
{
	for(rt i=h2[u];i;i=edge2[i].nxt)
	{
		int v=edge2[i].to;
		if(!st[v]){
			st[v]=1;dfs2(v);	
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin>>n>>m>>k>>A>>B;
	int x,y,z;
	for(rt i=1;i<=m;++i){
		cin>>x>>y>>z;
		add1(x,y,z);add2(y,x,z);
	}
	st[B]=1;
	dfs2(B);
	dfs1(A,0);
	if(!st[A]){
		cout<<-1;
		return 0;
	}
	if(ans!=0x3f3f3f3f)cout<<ans<<endl;
	else cout<<-1;
}

玄学复杂度

#include<bits/stdc++.h>
using namespace std;
#define rt register int
#define x1 X1
#define y1 Y1
#define x2 X2
#define y2 Y2
int n,m,ans;
int a[305][305];
inline bool check(int x1,int y1,int x2,int y2){
	int flag=1;
	for(rt i=x1,j=x2;i<=x2;++i,--j)
		for(rt k=y1,l=y2;k<=y2;++k,--l)
		{
			if(a[i][k]!=a[j][l]){
				return false;
			}
		}
	
	return true;
}
int main()
{
//	freopen("3.in","r",stdin);
//	freopen("3.out","w",stdout);
	ios::sync_with_stdio(false);
	cin>>n>>m;
	string s;
	for(rt i=1;i<=n;++i)
	{
		cin>>s;
		for(rt j=0;j<m;++j){
		
			if(s[j]=='1')a[i][j+1]=1;
			else a[i][j+1]=0;
		}
	}
	int lenmax=min(n,m);
	for(rt len=(ans<=2?2:ans);len<=lenmax;++len)//如果这一行不在最前速度会退化100倍以上??????
		for(rt i=1;i+len-1<=n&&i<n;++i)
			for(rt j=1;j+len-1<=m&&j<m;++j)
			{
				if(check(i,j,i+len-1,j+len-1))
					if(ans<len)ans=len;
			}
	if(!ans)cout<<-1;
	else cout<<ans;
}

线段树

#include <bits/stdc++.h>
using namespace std;
const int N = 100005, M = 55;
#define inf 0x3f3f3f3f
#define ll long long 
int n, k, m;
ll a[N];
struct node{
	int l, r, cnt, ans, left[M], right[M];
	ll zt[M], tz[M], val;
}tree[4 * N];
void pushup(int id, int l, int r) {
	tree[id].val = (tree[l].val | tree[r].val);
	for (int i = 1; i <= tree[l].cnt; ++i) {
		tree[id].zt[i] = tree[l].zt[i];
		tree[id].left[i] = tree[l].left[i];//记录子段位置
	}
	int tmp = tree[l].cnt;
	ll last = tree[l].val;
	for (int i = 1; i <= tree[r].cnt; ++i) {//前缀
		if ((last | tree[r].zt[i]) != last) {//1101 0111
			tree[id].zt[++tmp] = (last | tree[r].zt[i]);
			tree[id].left[tmp] = tree[r].left[i];//加入新位置
			last |= tree[r].zt[i];
		}
	}
	tree[id].cnt = tmp;
	for (int i = 1; i <= tree[r].cnt; ++i) {
		tree[id].tz[i] = tree[r].tz[i];
		tree[id].right[i] = tree[r].right[i];
	}
	tmp = tree[r].cnt; last = tree[r].val;
	for (int i = 1; i <= tree[l].cnt; ++i) {//后缀
		if ((last | tree[l].tz[i]) != last) {
			tree[id].tz[++tmp] = (last | tree[l].tz[i]);
			tree[id].right[tmp] = tree[l].right[i];
			last |= tree[l].tz[i];
		}
	}
	tree[id].ans = inf;
	int zz = 0;
	int MINN=min(tree[id].ans, tree[r].ans);
	if (MINN != inf) tree[id].ans = MINN;
	for (int i = tree[l].cnt; i >= 0; --i) {//最劣情况向最优情况
		while ( (tree[l].tz[i] | tree[r].zt[zz]) < (1ll << k) - 1 //(1ll << k)-1 表示所有数字存在
			&&  zz < tree[r].cnt) ++zz;//找到刚好满足条件的点
		if ((tree[l].tz[i] | tree[r].zt[zz]) < (1ll << k) - 1) break;//找遍全区间未能满足条件强行退出
		if (zz == 0) tree[r].left[zz] = tree[l].r;//如果前半个区间就能满足条件,tree[r]的第一个断点即tree[l].r
		tree[id].ans = min(tree[id].ans, tree[r].left[zz] - tree[l].right[i] + 1);//tree[r].left[zz] - tree[l].right[i]区间长度
	}
}
void build(int id, int l, int r) {
	tree[id].l = l;
	tree[id].r = r;
	if (l == r) {
		tree[id].cnt = 1;
		tree[id].zt[1] = tree[id].tz[1] = tree[id].val = (1ll << (a[l] - 1));//状态压缩
		tree[id].left[1] = tree[id].right[1] = l;
		if (k == 1) tree[id].ans = 1;
		else tree[id].ans = inf;
		return;
	}
	int mid = (l + r) >> 1;
	build(id * 2, l, mid);
	build(id * 2 + 1, mid + 1, r);
	pushup(id, id * 2, id * 2 + 1);
}
void change(int id, int x, int v) {
	if (tree[id].l == x && tree[id].r == x) {
		tree[id].zt[1] = tree[id].tz[1] = tree[id].val = (1ll << (v - 1));
		return;
	}
	int mid = (tree[id].l + tree[id].r) >> 1;
	if (x <= mid) change(id * 2, x, v);
	else change(id * 2 + 1, x, v);
	pushup(id, id * 2, id * 2 + 1);
}
int main() {
	ios::sync_with_stdio(false);
	int op, x, y;
	cin>>n>>k>>m;
	for (int i = 1; i <= n; ++i)cin>>a[i];
	build(1, 1, n);
	while (m--) {
		cin>>op;
		if (op == 1) {
			cin>>x>>y;
			change(1, x, y);
		} else {
			if (tree[1].ans == inf) cout<<-1<<endl;
			else cout<<tree[1].ans<<endl;
		}
	}
	return 0;
}
posted @ 2022-11-09 20:08  zyc_xianyu  阅读(30)  评论(0编辑  收藏  举报