11.20 考试总结

T1
打表找规律发现当2的n次方-1时f(n)=n;

#include<iostream>
#include<cstdio>
#define ull unsigned long long
using namespace std;
const int N=1e7+7;
ull l,r,ans;
ull b[100];
int main(){
	freopen("dynamic.in","r",stdin);
	freopen("dynamic.out","w",stdout);
	cin>>l>>r;
	b[0]=1;
	for(int i=1;i<=63;i++) b[i]=b[i-1]*2;
	for(int i=0;i<=63;i++){
		if(b[i]-1<(l+1)) continue;
		if(b[i]-1<r){
			ans++;
//			cout<<i<<" "<<b[i]-1<<" "<<r<<"\n";
		}else break;
	}
	cout<<ans;
	fclose(stdin);
	fclose(stdout);
	return 0;
}
/*
0 4

49 101
*/

T2
首先,固定走多少次的图论题可以用矩阵ksm来做;
然后,这道题可以发现,因为有机器人的参与,所每次转移的图是不确定的;
但是是有循环的,所以,可以把循环算出来,再算多余的;
这道题的话,12为一组就可以了,因为一共最多有12个不同的矩阵;
然后ksm即可,最后的时候别忘了剩下的

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=60;
const int inf=0x3f3f3f3f;
int n,m,k,num,s,t;
int dis[N][N];
int a[N];
struct mat{
	int v[N][N];
	void init(){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				v[i][j]=inf;
			}
		}
	}
	void mm(){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				v[i][j]=dis[i][j];
			}
		}
	}
	friend mat operator *(const mat a,const mat b){
		mat c;
		c.init();
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				for(int k=1;k<=n;k++){
					c.v[i][j]=min(c.v[i][j],max(a.v[i][k],b.v[k][j]));
				}
			}
		}
		return c;
	}
}ans,tt,q[20];

mat ksm(mat a,int b){
	mat res;
	res.init();
	res.v[s][s] = 0;
	for(;b;b>>=1){
		if(b&1) res=res*a;
		a=a*a;
	}
	return res;
}
int main(){
	freopen("simulation.in","r",stdin);
	freopen("simulation.out","w",stdout);
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			dis[i][j]=inf;
		}
	}
	for(int i=1;i<=m;i++){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		dis[x][y]=min(dis[x][y],z);
		dis[y][x]=min(dis[x][y],z);
	}
	for(int i=1;i<=12;i++) q[i].mm();
	scanf("%d%d%d",&num,&s,&t);
	for(int i=1;i<=num;i++){
		int x;
		scanf("%d",&x);
		for(int j=1;j<=x;j++) scanf("%d",&a[j]);
		for(int j=1;j<=12;j++){
			int p=j%x==0?a[x]:a[j%x];
			for(int l=1;l<=n;l++) q[j].v[l][p]=inf;
		}
	}
	tt=q[1];
//		for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++){
//			cout<<tt.v[i][j]<<" ";
//		}
//		cout<<"\n";
//	}
	for(int i=2;i<=12;i++) tt=tt*q[i];
	ans=ksm(tt,k/12);
	for(int i=1;i<=k%12;i++){
		ans=ans*q[i];
	}
	if(ans.v[s][t]==inf) printf("impossible");
	else cout<<ans.v[s][t];
	fclose(stdin);
	fclose(stdout);
	return 0;
}
/*
4 5 3
1 2 3
2 4 6
3 2 4
1 4 5
2 3 4
2 1 3
2 2 1
3 2 1 4

3 3 2
1 2 3
2 3 2
1 3 1
2 1 3
2 1 2
2 2 3
*/

posted @ 2020-11-21 08:18  Aswert  阅读(79)  评论(0编辑  收藏  举报