20160823群赛round6

来源:互联网 发布:炮火兰捏脸数据 编辑:程序博客网 时间:2024/05/16 18:21

群赛round5


今天模拟赛得分.........10   0   20   30(简直惨不忍睹......)

第一题上用了绝大多数的时间,然而并没有什么卵用==删了改,改了删,最后还是打了个表,把每个不存在原根(200以内)列了出来,1还判断错误.........第二题看了半天没懂..最后还是放弃了....等到第三题..题看懂了,方法也想到了,然而写不对,时间还不够了==今天实在没做好.


T1

题意:求一个数m的所有原根(应该是hdu4992)

题解:欧拉函数求出phi m  暴力枚举  判断  注意!!1有原根且为1

代码

#include <iostream>#include <stdio.h>#include <string.h>#include <math.h>#include <algorithm>using namespace std;int euler(int n){     int res=n,a=n;      for(int i=2;i*i<=a;i++){          if(a%i==0){              res=res/i*(i-1);             while(a%i==0) a/=i;          }      }      if(a>1) res=res/a*(a-1);      return res;  } int gcd(int x,int y){if(y==0) return x;return gcd(y,x%y);}int main(){freopen("math.in", "r", stdin);   <span style="white-space:pre"></span>freopen("math.out", "w", stdout);int m,mm;scanf("%d",&m);mm=euler(m);//cout<<mm<<endl;int flag=0;if(m==1) flag=0;    <span style="white-space:pre"></span>for (int i=1;i<=m;i++)    <span style="white-space:pre"></span>{    <span style="white-space:pre"></span>if (gcd(i,m)==1) {            <span style="white-space:pre"></span>int x=1;            <span style="white-space:pre"></span>int d=0;            <span style="white-space:pre"></span>for (int j=1;j<=mm;j++){                <span style="white-space:pre"></span>x=x*i%m;//ci fang mod m                <span style="white-space:pre"></span>if (x==1) {                    <span style="white-space:pre"></span>d=j;//Ordm(a)                    <span style="white-space:pre"></span>break;                <span style="white-space:pre"></span>}            <span style="white-space:pre"></span>}            <span style="white-space:pre"></span>if (d==mm) //a shi yuan gen{                <span style="white-space:pre"></span>flag=1;                <span style="white-space:pre"></span>printf("%d\n",i);            <span style="white-space:pre"></span>}        <span style="white-space:pre"></span>}}if(!flag) {if(m!=1) printf("-1\n");else printf("1\n");}return 0;}
可优化:i^    %m    快速幂


T2

题意:路分成了高度不同的N段,并用H[i]表示第i段高度。一共有n种泥土可用,它们都能覆盖给定的连续的k个部分。对于第i种泥土,它的价格为C[i],可以使得区间[i,min(n,i+k-1)]的路段的高度增加E[i]。要设定一种泥土使用计划,使得使用若干泥土后,这条路最低的高度尽量高,并且这个计划必须满足以下两点要求:(1)每种泥土只能使用一次。(2)泥土使用成本必须小于等于M。求出这个最低的高度最高是多少。

题解:二分  状压dp  二进制

dp[i][j](1<=i<=n,0<=j<=2^k)/i之前且第i个元素往前的k个是否使用的状态是j的时候的最小代价

代码(艾教的  自己写的太丑)

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;int n,m,k;int h[105],e[105],c[105];int dp[105][2055];int min(int x,int y){if (x==-1) return y;if (y==-1) return x;return x<y?x:y;//x<y  x; x>y  y}int can(int limit)//dp[i][j](1<=i<=n,0<=j<=2^k)//i之前且第i个元素往前的k个是否使用的状态是j的时候的最小代价{memset(dp,-1,sizeof(dp));dp[0][0]=0;for (int i=0;i<n;i++)for (int j=0;j<(1<<k);j++)if (dp[i][j]!=-1){int sum=0;for (int t=k-1;t>0;t--){if ((1<<t)&j)sum+=e[i-(k-1-t)];}if (sum+h[i+1]>=limit)dp[i+1][j>>1]=min(dp[i+1][j>>1],dp[i][j]);if (sum+h[i+1]+e[i+1]>=limit)dp[i+1][(j>>1)|(1<<(k-1))]=min(dp[i+1][(j>>1)|(1<<(k-1))],dp[i][j]+c[i+1]);}for (int j=0;j<(1<<k);j++)if (dp[n][j]!=-1)if (dp[n][j]<=m) return 1;return 0;}int main(){freopen("cover.in","r",stdin);freopen("cover.out","w",stdout);cin>>n>>m>>k;for (int i=1;i<=n;i++)cin>>h[i]>>e[i]>>c[i];int l=0,r=100000000;while (l+1<r)//二分查找 {int mid=(l+r)>>1;if (can(mid))l=mid; else r=mid-1;}if (can(l+1)) l++;cout<<l<<endl;}


T3

题意:

三个整数N,M,K,分别表示区域数,道路数,询问数。

接下来ui,vi,wi(ui≠vi,1≤ui,vi≤N,0<wi≤10^9),表示这条道路连接的区域和通过时间。

紧接着是两个整数ui,vi(ui≠vi,1≤ui,vi≤N),表示第M条道路连接的区域。

最后K行,每行一个正整数xi(0<xi≤10^9),表示目前第M条道路的通过时间。

分别计算出在这K个时段中逃离部落的最少时间,以帮助他们确定行动的时刻。

题解:spfa

先除去最后一条边(不定的)求1到任意点以及任意点到N的最短路

比较dis[1][S]+bian[S][T]+dis[T][N],dis[1][N]即可(不定边(S,T))

代码(标程)

#include<cstdio>#include<algorithm>#include<cstring>#include<queue>#define MAXN 200005#define MAXM 500005#define INF 4611686010000000000LL#define pr pair<LL, int>//pair (jian zhi dui)是 一种模版类型,每个pair 可以存储两个值,这两种值无限制。#define mp make_pair#define x first#define y secondusing namespace std ;typedef long long LL ;struct road {int x, next ;LL dis ;} r[MAXM*2] ;int N, M, K ;int ST, ED ;LL S[MAXN], T[MAXN] ;int st[MAXN], w, vis[MAXN] ;priority_queue< pr > q ;void add(int x, int y, LL dis){r[++w].x = y, r[w].next = st[x] ;r[w].dis = dis, st[x] = w ;}void SPFA(int x)//spfa qiu zui duan lu{int i, j, tmp ;LL now ;for(i = 1; i <= N; i ++) T[i] = INF ;T[x] = 0, q.push(mp(0, x)) ;while(!q.empty()){x = q.top().y, now = q.top().x, q.pop() ;if(-now > T[x]) continue ;now = -now ;for(i = st[x]; i; i = r[i].next)if(T[tmp=r[i].x] > T[x]+r[i].dis){T[tmp] = T[x]+r[i].dis ;q.push(mp(-T[tmp], tmp)) ;}}}int main(){freopen("monogatari.in", "r", stdin) ;freopen("monogatari.out", "w", stdout) ;int i, j ;int fr, to ;LL dt, tmp ;scanf("%d %d %d", &N, &M, &K) ;for(i = 1, tmp = 0; i < M; i ++){scanf("%d %d %I64d", &fr, &to, &dt) ;tmp += dt ;//zongshijian zuichangadd(fr, to, dt), add(to, fr, dt) ;}scanf("%d %d", &ST, &ED) ;SPFA(1) ;//1---ren yimemcpy(S, T, sizeof(S)) ;//nei cun kao bei han shuSPFA(N) ;//renyi---1for(i = 1; i <= K; i ++){scanf("%I64d", &dt) ;tmp = min(S[N], min(S[ST]+T[ED], S[ED]+T[ST])+dt) ;//bi jiaoif(tmp == INF) printf("+Inf\n") ;//no existelse printf("%I64d\n", tmp) ;}  return 0 ;}

题很好但今天做的实在不好,好多能拿上的没拿到,补题时也写的........

总之明天加油....


——20160823





0 0