Div.2还是稳定四题啊,E题还是没得办法,就争取四题再快点吧。
A(签到)
题意:写下s的第一个字符,在最右边写下s的第二个字符,在最左边写下s的第三个字符,以此类推生成字符串t,给出t,求s
找规律即可,写的还是有点慢,A题尽量控制在五分钟之内。
00:09 1A
#include <bits/stdc++.h> using namespace std; typedef long long int LL; #define st first #define nd second #define pb push_back #define mp make_pair #define pll pair <LL, LL> #define pii pair <int, int> #define rep(i,x) for(int i=1;i<=x;i++) const int N = 1e5+7; const int MX = 1e9+7; const LL INF = 1e18+9LL; int main(){ char s[100]; scanf("%s",s); int l=strlen(s); if(l%2){ cout<<s[l/2]; for(int i=l/2-1;i>=0;i--)cout<<s[l-i-1]<<s[i]; } else { for(int i=l/2-1;i>=0;i--)cout<<s[i]<<s[l-i-1]; } }
B(数学)
题意:给出n(1e6),k(1e3),求满足(x/k)*(x%k)=n的最小正整数解
发现k很小,因此枚举x%k的值即可求出所有x,更新最小值。
00:16 1A
#include <bits/stdc++.h> using namespace std; typedef long long int LL; #define st first #define nd second #define pb push_back #define mp make_pair #define pll pair <LL, LL> #define pii pair <int, int> #define rep(i,x) for(int i=1;i<=x;i++) const int N = 1e5+7; const int MX = 1e9+7; const LL INF = 1e18+9LL; int main(){ int n,k; scanf("%d%d",&n,&k); int ans=MX; rep(i,k-1){ if(n%i)continue; ans=min(n/i*k+i,ans); } cout<<ans; }
C(构造)
题意:给出三个方格的坐标,涂尽量少的方格使三个方格联通,输出方案。
观察发现显然答案是maxy-miny+maxx-minx+1,排序随便构造个方案即可。
00:40 1A
#include <bits/stdc++.h> using namespace std; typedef long long int LL; #define st first #define nd second #define pb push_back #define mp make_pair #define pll pair <LL, LL> #define pii pair <int, int> #define rep(i,x) for(int i=1;i<=x;i++) const int N = 1e3+7; const int MX = 1e9+7; const LL INF = 1e18+9LL; pii a[4]; pii ans[N*N]; int cnt; int cmp(pii a,pii b){ return a.st<b.st; } int main(){ rep(i,3){ int x,y; scanf("%d%d",&x,&y); a[i]=mp(x,y); } sort(a+1,a+4,cmp); for(int i=a[1].st;i<a[2].st;i++)ans[++cnt]=mp(i,a[1].nd); for(int i=a[2].st+1;i<=a[3].st;i++)ans[++cnt]=mp(i,a[3].nd); for(int i=min(min(a[1].nd,a[2].nd),a[3].nd);i<=max(max(a[1].nd,a[2].nd),a[3].nd);i++){ ans[++cnt]=mp(a[2].st,i); } cout<<cnt<<endl; rep(i,cnt)cout<<ans[i].st<<" "<<ans[i].nd<<endl; }
D(树,贪心)
题意:给出s,给一个树的每条边赋非负值wi,满足∑wi=s,求最小直径。
因为wi非负,直径一定连接了两个度为1的结点,即叶子或只有一个儿子的根,显然给靠近这些结点的边赋值更优,ans=s/sum(度为一的结点)*2。给其他边赋值会影响越多的路径长度,一定不会使答案更小。
01:22 1A
#include <bits/stdc++.h> using namespace std; typedef long long int LL; #define st first #define nd second #define pb push_back #define mp make_pair #define pll pair <LL, LL> #define pii pair <int, int> #define rep(i,x) for(int i=1;i<=x;i++) const int N = 1e5+7; const int MX = 1e9+7; const LL INF = 1e18+9LL; vector< int > to[N]; int sz[N]; void dfs(int x,int f){ if(to[x].size()==1)sz[x]=1; for(int i=0;i<to[x].size();i++){ if(to[x][i]!=f){ dfs(to[x][i],x); sz[x]+=sz[to[x][i]]; } } } int main(){ int n; double s; scanf("%d%lf",&n,&s); rep(i,n-1){ int u,v; scanf("%d%d",&u,&v); to[u].pb(v); to[v].pb(u); } dfs(1,0); int f=0; for(int i=0;i<to[1].size();i++) if(sz[to[1][i]]==sz[1]){ f=1; break; } if(f==1)printf("%.10lf",s/(sz[1]+1)*2); else printf("%.10lf",s/sz[1]*2); }