Gym .102021 .German Collegiate Programming Contest (GCPC 18)

谁借莪1个温暖的怀抱¢ 2024-04-17 05:30 189阅读 0赞

C .Coolest Ski Route

题意:给定带边权有向图,让你找一个最长的链,满足买个点最多遍历一次。

分析:记忆化搜索即可。

代码(by 胡):

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. #define lson l,m,rt<<1
  4. #define rson m+1,r,rt<<1|1
  5. #define pb push_back
  6. #define P pair<int,int>
  7. #define INF 1e18
  8. using namespace std;
  9. const int maxn = 200005;
  10. vector<pair<int,int> > G[maxn];
  11. int u[maxn],v[maxn],a[maxn],vis[maxn],d[maxn];
  12. int dp(int x,int fa){
  13. if(d[x]>0) return d[x];
  14. for(auto y:G[x]){
  15. if(y.first==fa) continue;
  16. dp(y.first,x);
  17. d[x]=max(d[x],d[y.first]+y.second);
  18. }
  19. return d[x];
  20. }
  21. int main(){
  22. int n,m;
  23. scanf("%d %d",&n,&m);
  24. while(m--){
  25. int u,v,w;
  26. scanf("%d %d %d",&u,&v,&w);
  27. G[u].push_back({v,w});
  28. }
  29. int ans=0;
  30. for(int i=1;i<=n;i++){
  31. ans=max(ans,dp(i,-1));
  32. }
  33. cout<<ans<<endl;
  34. return 0;
  35. }

D .Down the Pyramid

题意:金字塔的每一层的位置的值=下一层的两个值之和,现在给你最倒数第二层的值a1,a2…an,问你最后一层有多少种情况,满足所有数不小于0。被简单题卡了,当时就应该换一种思路。

分析:我们假设第一个位置位b0=x,那么b1=a1-x; b2=a2-b1=a2-a1+x.. 中间给限制让所有数大于等于0,则有x<=a1; x>=a1-a2; x<=a3+a2-a1 ; x>=…。

代码(by 胡):

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. #define lson l,m,rt<<1
  4. #define rson m+1,r,rt<<1|1
  5. #define pb push_back
  6. #define P pair<int,int>
  7. #define INF 1e18
  8. using namespace std;
  9. const int maxn = 1000005;
  10. ll a[maxn];
  11. int main(){
  12. int n;
  13. cin>>n;
  14. ll sum=0;
  15. ll Max,Min;
  16. for(int i=1;i<=n;i++){
  17. scanf("%I64d",&a[i]);
  18. if(i==1){
  19. Max=a[1];
  20. Min=0;
  21. }
  22. sum=a[i]-sum;
  23. if(i%2==0) Min=max(Min,-sum);
  24. else Max=min(Max,sum);
  25. }
  26. if(Min>Max) return puts("0")*0;
  27. cout<<Max-Min+1<<endl;
  28. return 0;
  29. }

E .Expired License

题意:给定你两个最多带5位小数的double型a,b,让你用用一对素数x y表示他们的比值。

思路:我们把a和b都乘1e5、除以gcd,再验证是否是素数即可。 注意特判1,1的情况(答案是2 2)。

代码(by 胡):

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. #define lson l,m,rt<<1
  4. #define rson m+1,r,rt<<1|1
  5. #define pb push_back
  6. #define P pair<int,int>
  7. #define INF 1e18
  8. using namespace std;
  9. const int maxn = 20000005;
  10. bool check[maxn];
  11. int prime[2000005];
  12. int tot;
  13. void init(){
  14. check[1]=1;
  15. for(int i=2;i<maxn;++i) {
  16. if(!check[i]) prime[tot++] = i;
  17. for(int j=0;j<tot;j++){
  18. if(i*prime[j]>maxn) break;
  19. check[i*prime[j]] = 1;
  20. if (i%prime[j] == 0 ) break;
  21. }
  22. }
  23. }
  24. int main(){
  25. int t;
  26. init();
  27. cin>>t;
  28. char s1[10],s2[10];
  29. while(t--){
  30. scanf("%s %s",s1,s2);
  31. ll a=0;
  32. ll b=0;
  33. int len=strlen(s1);
  34. int fg1=0,fg2=0;
  35. int pos1=0,pos2=0;
  36. for(int i=0;i<len;i++){
  37. if(s1[i]=='.') {
  38. pos1=1;
  39. continue;
  40. }
  41. else{
  42. a=a*10+s1[i]-'0';
  43. if(pos1) fg1++;
  44. }
  45. }
  46. len=strlen(s2);
  47. for(int i=0;i<len;i++){
  48. if(s2[i]=='.') {
  49. pos2=1;
  50. continue;
  51. }
  52. else{
  53. b=b*10+s2[i]-'0';
  54. if(pos2) fg2++;
  55. }
  56. }
  57. if(fg1>fg2){
  58. fg2=fg1-fg2;
  59. while(fg2){
  60. b*=10;
  61. fg2--;
  62. }
  63. }else if(fg2>fg1){
  64. fg1=fg2-fg1;
  65. while(fg1){
  66. a*=10;
  67. fg1--;
  68. }
  69. }
  70. ll gcd=__gcd(a,b);
  71. a=a/gcd;
  72. b=b/gcd;
  73. if(a==1&&b==1){
  74. puts("2 2");
  75. continue;
  76. }
  77. if(!check[a]&&!check[b]) printf("%I64d %I64d\n",a,b);
  78. else puts("impossible");
  79. }
  80. return 0;
  81. }

F .Fighting Monsters

题意:给定N个怪兽,问是否能选处两个怪兽,使得他们相互攻击,最后活着的怪兽剩1滴血。

分析:判断是否存在相邻的Fibonacci数。

代码(by 胡):

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. #define lson l,m,rt<<1
  4. #define rson m+1,r,rt<<1|1
  5. #define pb push_back
  6. #define P pair<int,int>
  7. #define INF 1e18
  8. using namespace std;
  9. const int maxn = 1000005;
  10. int x[maxn];
  11. int pos[maxn];
  12. int a[maxn];
  13. int main(){
  14. a[1]=1;
  15. a[2]=1;
  16. for(int i=3;i<=32;i++){
  17. a[i]=a[i-1]+a[i-2];
  18. }
  19. int n;
  20. cin>>n;
  21. for(int i=1;i<=n;i++){
  22. scanf("%d",&x[i]);
  23. }
  24. int a1,b1;
  25. for(int i=1;i<=32;i++){
  26. a1=0;
  27. b1=0;
  28. for(int j=1;j<=n;j++){
  29. if(x[j]==a[i]){
  30. a1=j;
  31. break;
  32. }
  33. }
  34. for(int j=1;j<=n;j++){
  35. if(j==a1) continue;
  36. if(x[j]==a[i+1]){
  37. b1=j;
  38. break;
  39. }
  40. }
  41. if(a1&&b1){
  42. cout<<a1<<" "<<b1<<endl;
  43. return 0;
  44. }
  45. }
  46. puts("impossible");
  47. return 0;
  48. }

H .Hyper Illuminati

题意:给定一个数N(<1e16),问是否存在n和s,满足1^n+2^n+3^n+…s^n=N;输出n+1,s;

思路:2^54>1e16,n的范围很小,暴力就好了

代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. ll ans=0,m;
  5. int main(){
  6. scanf("%lld",&m);
  7. for(ll i=2;i<=54;i++) {
  8. ans=0;
  9. for(ll j=1;j<=m;j++){
  10. ll tp=1;
  11. for(ll k=1;k<=i;k++) {
  12. if(tp>m/j) {
  13. tp=m+1;
  14. break;
  15. }
  16. tp*=j;
  17. }
  18. if(tp>m) break;
  19. ans+=tp;
  20. if(ans==m) {
  21. printf("%lld %lld\n",i+1,j);
  22. return 0;
  23. }
  24. else if(ans>=m) break;
  25. }
  26. }
  27. printf("impossible\n");
  28. return 0;
  29. }

I .It’s Time for a Montage

水题

L. Logic Puzzle

题意:扫雷,复原雷图。

思路:从左上顶点开始,如果一个点a[i][j]=1,那么a[i+1][j+1]一定是雷,然后把周围9个点都-1;最后遍历一遍,全是0就输出雷的排列,否则输出impossible。

代码:

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. const int N=110;
  5. int n,m,a[N][N],vis[N][N];
  6. int x[9]= {1,1,1,-1,-1,-1,0,0,0};
  7. int y[9]= {1,-1,0,1,-1,0,1,-1,0};
  8. int main() {
  9. scanf("%d%d",&n,&m);
  10. for(int i=0;i<=n+1;i++)
  11. for(int j=0;j<=m+1;j++)
  12. scanf("%d",&a[i][j]);
  13. for(int i=0;i<=n;i++) {
  14. for(int j=0;j<=m;j++) {
  15. if(a[i][j]) {
  16. vis[i+1][j+1]=1;
  17. for(int k=0;k<9;k++) {
  18. if(i+1+x[k]>=0&&i+1+x[k]<=n+1&&j+1+y[k]>=0&&j+1+y[k]<=m+1)
  19. a[i+1+x[k]][j+1+y[k]]--;
  20. }
  21. }
  22. }
  23. }
  24. for(int i=0;i<=n+1;i++) {
  25. for(int j=0;j<=m+1;j++)
  26. if(a[i][j]) {
  27. printf("impossible\n");
  28. return 0;
  29. }
  30. }
  31. for(int i=1;i<=n;i++) {
  32. for(int j=1;j<=m;j++)
  33. if(vis[i][j]) printf("X");
  34. else printf(".");
  35. printf("\n");
  36. }
  37. return 0;
  38. }

发表评论

表情:
评论列表 (有 0 条评论,189人围观)

还没有评论,来说两句吧...

相关阅读