2018-01-20
两层循环
代码如下:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <stack> #include <queue> typedef long long ll; using namespace std; const int MOD=1e9+7; int main() { int n,a,b,c,maxx=0; scanf("%d%d%d%d",&n,&a,&b,&c); for(int i=0;i<=n/a;i++) for(int j=0;j<=n/b;j++) if((n-a*i-b*j)>=0&&(n-a*i-b*j)%c==0) { maxx=max(maxx,i+j+(n-a*i-b*j)/c); } printf("%d\n",maxx); return 0; }
B - s-palindrome
判断该字符串是否是镜像的,模拟 注意‘n’,‘m’并不镜像
代码如下:
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <stack> #include <queue> typedef long long ll; using namespace std; const int MOD=1e9+7; char str[]={‘A‘,‘H‘,‘I‘,‘M‘,‘O‘,‘o‘,‘T‘,‘U‘,‘V‘,‘v‘,‘W‘,‘w‘,‘X‘,‘x‘,‘Y‘}; const int N=1e3+7; char ch[N]; int path(char c) { for(int i=0;i<15;i++) if(c==str[i]) return 1; return 0; } int lp(char c,char d) { if(c==‘d‘&&d==‘b‘) return 1; if(c==‘b‘&&d==‘d‘) return 1; if(c==‘p‘&&d==‘q‘) return 1; if(c==‘q‘&&d==‘p‘) return 1; return 0; } int lk() { int l=0,r=strlen(ch)-1; while(l<=r) { if((ch[l]==ch[r]&&path(ch[l]))||lp(ch[l],ch[r])) { l++;r--; } else return 0; } return 1; } int main() { scanf("%s",ch); if(lk()) puts("TAK"); else puts("NIE"); return 0; }
额 题意很重要
就是这个图的点能否被切分成两个集合,同一个集合中的点,不能有边相连。所以最后所有点都会被划分到两个集合内。
找出集合的大小m0,m1,边数就等于m0*m1, 题中有n-1边是原有的,答案即为m0*m1-(n-1)
dfs
代码如下:
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <map> #include <vector> using namespace std; typedef long long ll; const int N=1e5+7; vector<int>edge[N]; int vis[N]; ll m0=0,m1=0; void dfs(int n,int flag) { if(flag) m0++; else m1++; vis[n]=1; for(int i=0;i<edge[n].size();i++) if(!vis[edge[n][i]]) dfs(edge[n][i],!flag); } int main() { int n,u,v; cin>>n; memset(vis,0,sizeof(vis)); for(int i=0;i<n-1;i++) { cin>>u>>v; edge[u].push_back(v); edge[v].push_back(u); } dfs(1,0); cout<<m0*m1-(n-1)<<endl; return 0; }
题意:
已知a序列,以及c序列的大小的排名, c[i]=b[i]-a[i],且a[i],b[i]均是[l-r]范围内,求b序列,若不存在输出-1
操作顺序是从c序列的小到大,首先找到一个最小值 minn=(l-a[vis[0]]),然后下一个数为minn+1 ,b[i]=minn+1+a[i],若b[i]不在[l-r]范围内结束,输出-1 ,否则 b[i]=max(b[i],l) 继续操作
代码如下:
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <stack> #include <queue> using namespace std; typedef long long ll; const int N=1e5+7; const int INF=1e9+7; int a[N],b[N]; int vis[N]; int main() { int n,l,r,p; scanf("%d%d%d",&n,&l,&r); for(int i=0;i<n;i++) scanf("%d",&a[i]); for(int i=0;i<n;i++) { scanf("%d",&p); vis[p-1]=i; } int minn=-INF,flag=0; for(int i=0;i<n;i++) { if(i==0) { b[vis[i]]=l; minn=l-a[vis[i]]; } else { int x=minn+1+a[vis[i]]; if(x>r) { flag=1; break; } else b[vis[i]]=max(l,x); minn=b[vis[i]]-a[vis[i]]; } } if(flag) puts("-1"); else { for(int i=0;i<n;i++) printf("%d%c",b[i],i==n-1?‘\n‘:‘ ‘); } return 0; }
题意:
给n个能源箱,问最后所有能量箱都为一样的最大值
给n个能源箱,问最后所有能量箱都为一样的最大值
能量转移会损失能量
二分 能源的范围[l-r]
代码如下:
View Code
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int N=1e4+7; int main() { double l=1000,r=0; int n,k; double a[N]; scanf("%d%d",&n,&k); for(int i=0;i<n;i++) { scanf("%lf",&a[i]); l=min(l,a[i]); r=max(r,a[i]); } while(l+1e-9<=r) { double mid=(l+r)*1.0/2.0; double ans=0; for(int i=0;i<n;i++) { if(a[i]>mid) { ans+=mid; ans+=(a[i]-mid)*(100-k)*1.0/100.0; } else ans+=a[i]; } if(ans>n*mid) l=mid; else r=mid; } printf("%.9lf\n",l); return 0; }