自家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;
}