Police Stations
思路见
巧妙的bfs题,利用了bfs最短路的性质
代码实现的时候也有很多坑。
访问过的顶点显然要开vis数组,
坑1:边也要开vis数组,因为最短路的边肯定不能删,删过的边也不能重复计入答案
坑2:见代码49行。加入d的限制反而WA了。其实不用加上距离d的限制。因为本来就可行,而bfs找到是最短路,同一连通块的距离是不会超过d的
#include<bits/stdc++.h> #define RD1(x) scanf("%d",&x) #define RD2(x,y) scanf("%d %d",&x,&y) #define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z) #define RDL1(x) scanf("%lld",&x) #define RDL2(x,y) scanf("%lld %lld",&x,&y) #define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z) #define CLR(x) memset(x,0,sizeof(x)) #define maxn (300000+10) #define lson (rt<<1) #define rson (rt<<1|1) #define mod (1000000007) #define pi acos(-1) #define eps 1e-14 #define acc ios::sync_with_stdio(false) #define inf 0x3f3f3f3f #define INF(x) memset(x,inf,sizeof(x)) #define CLRQ(Q) while(!(Q).empty())(Q).pop() #define see(x) (cerr<<(#x)<<'='<<(x)<<' ') #define NL printf("\n") using namespace std; typedef long long ll; typedef unsigned long long ull; int n,k,d; int loc[maxn]; bool vis[maxn]; bool vise[maxn]; queue<pair<int,int> >Q; int head[maxn],to[maxn<<1],pre[maxn<<1],tot,id[maxn<<1],fa[maxn]; void adde(int u,int v,int i) { to[++tot]=v,pre[tot]=head[u],head[u]=tot,id[tot]=i; } int ans[maxn],num; int main() { RD3(n,k,d);for(int i=0;i<k;i++)RD1(loc[i]); sort(loc,loc+k); k=unique(loc,loc+k)-loc; for(int i=0;i<n;i++){Q.push(pair<int,int>(loc[i],0));vis[loc[i]]=1;} for(int i=1;i<n;i++) { int u,v;RD2(u,v);adde(u,v,i),adde(v,u,i); } while(!Q.empty()) { pair<int,int>p=Q.front();Q.pop(); int u=p.first,dis=p.second; // if(dis==d)continue; for(int i=head[u];i;i=pre[i]) { int v=to[i],e=id[i];if(fa[u]==v)continue; if(vis[v]) { if(!vise[e]) { vise[e]=1; ans[num++]=e; } continue; } vis[v]=1;vise[e]=1;fa[v]=u; Q.push(pair<int,int>(v,dis+1)); } } printf("%d\n",num); for(int i=0;i<num;i++)printf("%d ",ans[i]); return 0; }
比较玄学的暴力题
一开始想用dp,结果TLE
官方粗略证明:
设dp[i]是a转移到i的最小步数。
dp[i]是单调的
因此直接贪心,每次减去最大的,一旦b==a了就break
坑:不得不优化的地方
如果
那么
所以暴力的过程中把没用的xi去掉,不然又会TLE
#include<bits/stdc++.h> #define RD1(x) scanf("%d",&x) #define RD2(x,y) scanf("%d %d",&x,&y) #define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z) #define RDL1(x) scanf("%lld",&x) #define RDL2(x,y) scanf("%lld %lld",&x,&y) #define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z) #define CLR(x) memset(x,0,sizeof(x)) #define maxn (100000+10) #define lson (rt<<1) #define rson (rt<<1|1) #define mod (1000000007) #define pi acos(-1) #define eps 1e-14 #define acc ios::sync_with_stdio(false) #define inf 0x3f3f3f3f #define INF(x) memset(x,inf,sizeof(x)) #define CLRQ(Q) while(!(Q).empty())(Q).pop() #define see(x) (cerr<<(#x)<<'='<<(x)<<' ') #define NL printf("\n") using namespace std; typedef long long ll; typedef unsigned long long ull; int n,x[maxn],a,b,sz; int main() { RD1(n);for(int i=0;i<n;i++)RD1(x[i]); RD2(a,b);if(a==b){printf("0");return 0;} sort(x,x+n);sz=unique(x,x+n)-x; //for(int i=0;i<sz;i++)see(x[i]),NL; int ans=0; while(a>b) { int tmp=a-1; for(int i=0;i<sz;i++) { if(a-a%x[i]>=b)tmp=min(tmp,a-a%x[i]); } a=tmp,ans++; if(a==b)break; while(sz&&a-a%x[sz-1]<b)sz--; } printf("%d",ans); return 0; }
巧妙的数论问题
坑:每种ai数量是无限的,而且0总是合法的,一个都不选
思路:
根据定理,(a1,a2,a3,,,,an)可以表示的数的集合是g=gcd(a1,a2,a3......an)及其倍数
答案就是集合
g*k开始%k就重复了
#include<bits/stdc++.h> #define RD1(x) scanf("%d",&x) #define RD2(x,y) scanf("%d %d",&x,&y) #define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z) #define RDL1(x) scanf("%lld",&x) #define RDL2(x,y) scanf("%lld %lld",&x,&y) #define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z) #define CLR(x) memset(x,0,sizeof(x)) #define maxn (100000+10) #define lson (rt<<1) #define rson (rt<<1|1) #define mod (1000000007) #define pi acos(-1) #define eps 1e-14 #define acc ios::sync_with_stdio(false) #define inf 0x3f3f3f3f #define INF(x) memset(x,inf,sizeof(x)) #define CLRQ(Q) while(!(Q).empty())(Q).pop() #define see(x) (cerr<<(#x)<<'='<<(x)<<' ') #define NL printf("\n") using namespace std; typedef long long ll; typedef unsigned long long ull; int n,k,a[maxn]; set<int>S; int main() { RD2(n,k); int rt;RD1(rt); for(int i=1;i<n;i++){int t;RD1(t);t%=k;rt=__gcd(t,rt);} for(int i=0;i<k;i++)S.insert(i*rt%k); printf("%d\n",S.size()); for(set<int>::iterator it=S.begin();it!=S.end();it++) { printf("%d ",*it); } return 0; }