Codeforces Round #499 (Div. 2)
又困又累总之状态不是很好。。就拿个小号随便打打了。。。
A.n个小写字母选k个, 若选了一个字符c,那么它前面的字母和与它相邻的右边的第一个字母不能选,求最小价值.
排序后xjb贪一贪...智障错误wa+1.。。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 #include <cstring> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define writeln printf("\n") 11 const int N=1e5+50; 12 using namespace std; 13 int n,k,tot,cnt,ans,now; 14 int a[N]; 15 char s[N]; 16 int read() 17 { 18 int s=0,t=1; char c; 19 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 20 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 21 return s*t; 22 } 23 ll readl() 24 { 25 ll s=0,t=1; char c; 26 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 27 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 28 return s*t; 29 } 30 int main() 31 { 32 n=read(); k=read(); 33 scanf("%s",s); 34 for (int i=0;i<n;i++) 35 a[++tot]=s[i]-'a'+1; 36 sort(a+1,a+tot+1); 37 for (int i=1;i<=tot;i++){ 38 if (i==1) { 39 //out(a[i]); writeln; 40 ans+=a[i]; cnt++; now=a[i]; 41 } 42 else { 43 if (a[i]-now>1) ans+=a[i],cnt++,now=a[i];//,out(a[i]),writeln; 44 } 45 if (cnt==k) break; 46 } 47 if (cnt!=k){ 48 out(-1); 49 return 0; 50 } 51 out(ans); 52 return 0; 53 }
B.n个人,m个食物袋,每个人每天用的食物袋类型与前一天用的相同,求他们能用多少天.
一开始思路错了。。后来想到只要二分一下答案检查是否可行就好了。。。
由于m很小,枚举一波答案即可。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 #include <cstring> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define writeln printf("\n") 11 const int N=1e5+50; 12 using namespace std; 13 int n,m,h,tot,mx,maxn,ans; 14 int a[N],b[N],cnt[N],num[N]; 15 int read() 16 { 17 int s=0,t=1; char c; 18 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 19 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 20 return s*t; 21 } 22 ll readl() 23 { 24 ll s=0,t=1; char c; 25 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 26 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 27 return s*t; 28 } 29 int main() 30 { 31 n=read(); m=read(); 32 for (int i=1;i<=m;i++) 33 a[i]=read(),b[a[i]]++,mx=max(mx,a[i]); 34 for (int i=1;i<=mx;i++) 35 if (b[i]>0) cnt[++tot]=b[i]; 36 for (int i=1;i<=m;i++){ 37 h=0; 38 for (int j=1;j<=tot;j++) 39 h+=cnt[j]/i; 40 if (h>=n) ans=i; 41 else break; 42 } 43 out(ans); 44 return 0; 45 }
C.有n个星球,路线为1-->2-->3-->.....-->n-->1,飞船最开始有个重量m,在1星球的时候可以加油,后面只能用油不能加,设在第i个星球时飞船重量为x,当在第i个星球起飞时,消耗x/a[i]的油量,在第i个星球降落消耗x/b[i]油量,求最小加油量使其完成路线。
太困懒得思考就滚去碎觉了。。然而早上起来想了不到5min就写出来了。。。
考虑倒着推,从最后一次降落考虑,设降落前重量为x,那么有:x-x/b[1]=m,转化一下得b[1]/(b[1]-1)x=m,那么x=m*b[1]/(b[1]-1),然后用x代替m一直推回去就好了..
由于答案最大1e9,判一下答案如果是inf就-1.
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #define ll long long 9 #define out(a) printf("%d",a) 10 #define writeln printf("\n") 11 const int N=1e5+50; 12 using namespace std; 13 int n,m; 14 int a[N],b[N]; 15 double now; 16 bool flag=false; 17 int read() 18 { 19 int s=0,t=1; char c; 20 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 21 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 22 return s*t; 23 } 24 ll readl() 25 { 26 ll s=0,t=1; char c; 27 while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();} 28 while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();} 29 return s*t; 30 } 31 int main() 32 { 33 n=read(),m=read(); 34 for (int i=1;i<=n;i++){ 35 a[i]=read(); 36 } 37 for (int i=1;i<=n;i++){ 38 b[i]=read(); 39 } 40 now=(double)(m*b[1])/(b[1]-1); 41 now=(double)(now*a[n])/(a[n]-1); 42 for (int i=1;i<=n-1;i++) 43 now=(double)(now*a[i])/(a[i]-1),now=(double)(now*b[i+1])/(b[i+1]-1); 44 if (now-n>1e10) puts("-1"); 45 else printf("%.10lf",now-m); 46 return 0; 47 }
总结:写题不要有畏难情绪,其实仔细阅读认真思考还是很简单地能够写出来的。