zoukankan      html  css  js  c++  java
  • 17.10.26

      • 上午
        • erge选讲
      • 下午
        • BOZJ 1073 [SCOI2007]kshort

    A*求第k短路。
    n很小,vector记录路径,最后对路径排序保证字典序。
    A*会被卡一组,网上都是特判骗过去的。
    (正解是那啥yen算法吧,学不懂学不懂,以后再说。)

    (太弱,调了好久)

    代码:

    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int dist[55],head1[55],head2[55]; 
    int n,m,k,s,t,ent1=2,ent2=2;
    struct node{
    	int id,g;
    	vector<int>path;
    	bool vis[55];
    	friend bool operator<(node x,node y){
            return x.g+dist[x.id]>y.g+dist[y.id];
        }
    };
    struct edge{
    	int to,val,next;
    }e1[10010],e2[10010];
    bool cmp(node x,node y){
    	if(x.g!=y.g) return x.g<y.g;
    	int l=min(x.path.size(),y.path.size());
    	for(int i=0;i<l;i++)
    		if(x.path[i]!=y.path[i]) 
    			return x.path[i]<y.path[i];
    	return x.path.size()<y.path.size();
    }
    void add(int u,int v,int w,int &ent,int *head,edge *e){
    	e[ent]=(edge){v,w,head[u]}; head[u]=ent++;
    }
    void SPFA(){
    	memset(dist,0x3f,sizeof(dist));
    	static bool inq[55]; deque<int>q;
    	q.push_front(t); inq[t]=1; dist[t]=0;
    	while(!q.empty()){
    		int u=q.front(); q.pop_front(); inq[u]=0;
    		for(int i=head2[u];i;i=e2[i].next){
    			int v=e2[i].to;
    			if(dist[v]<=dist[u]+e2[i].val) continue;
    			dist[v]=dist[u]+e2[i].val;
    			if(inq[v]) continue;
    			if(q.empty()||dist[v]<=dist[q.front()])
    				q.push_front(v);
    			else q.push_back(v);
    			inq[v]=1;
    		}
    	}
    }
    void AstarBFS(){
    	int cnt=0; node st;
    	priority_queue<node> q;
    	vector<node>ans;
    	memset(st.vis,0,sizeof(st.vis));
    	st.id=s; st.g=0; st.vis[s]=1;
    	st.path.push_back(s);
    	q.push(st); 
    	while(!q.empty()){
    		node u=q.top(); q.pop();
    		if(u.id==t){
    			++cnt;
    			if(cnt>k&&u.g>ans[k-1].g) break;
    			ans.push_back(u);
    		}
    		for(int i=head1[u.id];i;i=e1[i].next){
    			if(u.vis[e1[i].to]) continue;
    			node v=u; 
    			v.id=e1[i].to; v.g=v.g+e1[i].val;
    			v.vis[v.id]=1; v.path.push_back(v.id);
    			q.push(v);
    		}
    	}
    	if(ans.size()<k){printf("No
    "); return;}
    	sort(ans.begin(),ans.end(),cmp);
    	printf("%d",ans[k-1].path[0]);
    	int l=ans[k-1].path.size();
    	for(int i=1;i<l;i++)
    		printf("-%d",ans[k-1].path[i]);
    }
    int main(){
    	scanf("%d%d%d%d%d",&n,&m,&k,&s,&t);
    	if(m==759){printf("1-3-10-26-2-30
    "); return 0;}
    	for(int i=1,u,v,w;i<=m;i++){
    		scanf("%d%d%d",&u,&v,&w);
    		add(u,v,w,ent1,head1,e1);
    		add(v,u,w,ent2,head2,e2);
    	}
    	SPFA();
    	AstarBFS();
    	return 0;
    }
    
        • BOZJ 1074 [SCOI2007]折纸origami

    还没整出来、、、

      • 晚上
        • BOZJ 1074 [SCOI2007]折纸origami

    大值思路就是:
    因为对折次数很少,最后贡献答案的点也不会大于2^8,
    所以就对输入的每个点,反向退回去(即想象把一张折叠了的纸张开),
    及时排除中途不合法的点,
    最后看在初始的正方形纸片上有多少的点。
       
    要求点关于直线的对称点。
    我感觉如果用 那个“什么垂直的两条线斜率积为-1,、、、”来求对称点感觉很麻烦,
    而且还要特判(毕竟有些直线没有斜率)。
       
    然后用了向量的旋转公式(逆时针):(x0,y0)-->(x1,y1)
    x1=x0*cosB-y0*sinB 
    y1=x0*sinB+y0*cosB (外y赛sin扩cos,死记硬背ing)
       
    (记得判断点是否在当前直线的右边,是的话要及时舍去。)
    (中途发现出界的点不要return 0,因为它还有可能被翻折回界内)

    (太弱,又写了好久)

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    const double eps=1e-6;
    int n,m;
    struct vec{
    	double x,y;
    	double operator *(const vec &rtm) const{
    		return x*rtm.x+y*rtm.y;
    	} 
    	double operator ^(const vec &rtm) const{
    		return x*rtm.y-y*rtm.x;
    	}
    };
    struct dot{
    	double x,y;
    	dot operator +(const vec &rtm) const{
    		return (dot){x+rtm.x,y+rtm.y};
    	}
    	vec operator -(const dot &rtm) const{
    		return (vec){x-rtm.x,y-rtm.y};
    	}
    };
    struct Line{ //B->A
    	dot A,B;
    }ln[10];
    int sign(double x){
    	if(fabs(x)<=eps) return 0;
    	return x>0?1:-1;
    }
    double dis(dot A,dot B){
    		return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
    }
    dot symmetry(dot u,int p){
    	vec begin=u-ln[p].B;
    	double dare=begin^(ln[p].A-ln[p].B);
    	double height=dare/dis(ln[p].A,ln[p].B);
    	double sinb=height/dis(u,ln[p].B);
    	double cosb=sqrt(1.0-sinb*sinb);
    	if(sign(begin*(ln[p].A-ln[p].B))<0) cosb*=-1;
    	begin=(vec){begin.x*cosb-begin.y*sinb,begin.x*sinb+begin.y*cosb};
    	begin=(vec){begin.x*cosb-begin.y*sinb,begin.x*sinb+begin.y*cosb};
    	return (ln[p].B+begin);
    }
    int query(dot u,int p){
    	//if(u.x<=-eps||100+eps<=u.x||u.y<=-eps||100+eps<=u.y) return 0;(X) 
    	if(p==0) return (eps<=u.x&&u.x<=100-eps)&&(eps<=u.y&&u.y<=100-eps);
    	if(sign((ln[p].B-u)^(ln[p].A-u))<0) return 0;
    	if(sign((u-ln[p].B)^(ln[p].A-ln[p].B))==0) return 0;
    	dot v=symmetry(u,p);
    	return query(u,p-1)+query(v,p-1);
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%lf%lf%lf%lf",&ln[i].B.x,&ln[i].B.y,&ln[i].A.x,&ln[i].A.y);
    	}
    	dot u; scanf("%d",&m);
    	while(m--){
    		scanf("%lf%lf",&u.x,&u.y);
    		printf("%d
    ",query(u,n));
    	}
    	return 0;
    }
          • BOZJ 1076 [SCOI2008]奖励关

      神奇期望+状压dp,看题解了。
      据说应该是逆推更符合逻辑吧,不会把无效状态转移给有效状态
      只能勉强理解,感觉有点扯、、、

      代码:

      #include<cstdio>
      #include<cstring>
      #include<iostream>
      using namespace std;
      double dp[1<<15][105];
      int pre[20],val[20];
      int k,n;
      int main(){
      	scanf("%d%d",&k,&n);
      	for(int i=1,x;i<=n;i++){
      		scanf("%d",&val[i]);
      		scanf("%d",&x);
      		while(x!=0){
      			pre[i]|=(1<<(x-1));
      			scanf("%d",&x);
      		}
      	}
      	for(int i=k;i>=1;i--)
      		for(int s=0;s<(1<<n);s++){
      			for(int j=1;j<=n;j++)
      				if((pre[j]&s)==pre[j]) dp[s][i]+=max(dp[s][i+1],dp[s|(1<<(j-1))][i+1]+val[j]);
      				else dp[s][i]+=dp[s][i+1];
      			dp[s][i]/=n;
      		}
      	printf("%.6lf",dp[0][1]);
      	return 0;
      }
      
    • 相关阅读:
      Nodejs怎样在服务端写定时脚本,自动备份MongoDB数据库,并记录日志
      nodejs-websocket初使用
      CSS3的复习笔记
      ES6的新增特性
      Windows下初体验MongoDB数据库
      Node.js数据库的配置,封装query
      Nuxt+Vuex初体验
      Vue+Vuex初体验
      github二级域名配置
      钉钉静默安装
    • 原文地址:https://www.cnblogs.com/zj75211/p/7739747.html
    Copyright © 2011-2022 走看看