<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      河南工大2024新生周賽(7)----命題人 劉義 題解

      問題 A: 圓:

      這是一個數學題,畫圖可得,4 個圓時,分割成 14 個區域,可以推導出結論:當圓為0個時,區域數為1個,當圓有x個的時候,區域數有x*x-x+2;

      #include<bits/stdc++.h>
      using namespace std;
      #define int long long
      int n;
      signed main(){
          int a,b;//a為圓的個數,b為區域數
          cin>>n;
          while(n--)
          {
              cin>>a;
              if(a==0)
              b=1;
              else
              b=a*a-a+2;
              cout<<b<<" ";
          }
          return 0;
      }

      問題 B: 旅人分寶:

      這是一個經典的海盜分金問題,每個旅人只會選擇一個對自己最有利的情況,并且要求50%以上的同意,所以當老大給一半的人每一個人一個金幣,他們就會同意了。

      #include<bits/stdc++.h>
      using namespace std;
      int t;
      int n,x;
      int main()
      {
          cin>>t;
          while(t--)
          {
              cin>>n>>x;
              if(x%2==0)
              {
                  cout<<n-x/2+1<<endl;
              }
              else
              {
                  cout<<n-x/2<<endl;
              }
          }
          return 0;
      }

       

      問題 C: A*B:

      經典的高精度乘法:

      #include <stdio.h>
      #include <string.h>
      
      //翻轉函數
      void reverse (int d[510], int len) {
          int temp, mid = len/2;
          for (int i = 0, j = len - 1; i < mid, j >= mid; i++, j--) {
              temp = d[i];
              d[i] = d[j];
              d[j] = temp;
          }
      }
      
      int main () {
          char s1[2005], s2[2005];
          int a[2005], b[2005], c[4010] = {0};
          scanf("%s", s1);
          scanf("%s", s2);
          int lena = strlen(s1);
          int lenb = strlen(s2);
          int lenc = lena + lenb;
          
          //將char的1轉為int的1
          for (int i = 0; i < lena; i++) {
              a[i] = s1[i] - '0';
          }
          for (int i = 0; i < lenb; i++) {
              b[i] = s2[i] - '0';
          }
          
          reverse(a, lena);
          reverse(b, lenb);
          
          //核心代碼
          for (int i = 0; i < lenb; i++) {
              for (int j = 0; j < lena; j++) {
                  c[i+j] += b[i] * a[j];
                  c[i+j+1] += c[i+j] / 10;
                  c[i+j] = c[i+j] % 10;
              }
          }
          
          //處理前導0
          lenc = lenc - 1;
          while (c[lenc] == 0 && lenc >= 1) {
              lenc--;
          }
          
          //輸出
          for (int i = lenc; i >= 0; i--) {
              printf("%d", c[i]);
          }
          
          return 0;
      }

      問題 D: 時間加速器:

      首先考慮暴力做法,即枚舉最終答案ans,對于第一個可行的ans一定是最優解(在ans時間內可以完成ans+t(t>=0)的時間內也就一定可以完成)由于N<=500000的數據范圍絕對會TLE,因此需要優化。

      接下來考慮優化,由于之前提到的性質,設f(i)表示在i時間內有無可能完成,那么f數組必定滿足單調性。那么我們可以二分最終答案ans,對于每一個ans對其進行暴力check:對于每一件任務,如果它能在ans天內完成(完成度<=ans*a),那么就不必使用時間加速器,接下來處理必須使用時間加速器的情況,當i號任務不能被直接完成時,我們需要用((x[i]-a*mid)%b==0?(x[i]-a*mid)/b:(x[i]-a*mid)/b+1;)次時間加速器進行完成,最后只需看時間加速器使用總數是否小于等于mid即可。

      #include<iostream>
      #define int long long
      using namespace std;
      int n,a,b,x[600006];
      bool check(int mid)//判斷函數 
      {
          int tot=0;
          for(int i=1;i<=n;i++)
          {
              if(x[i]<=mid*a)continue;
              else 
              {
                  
                  if((x[i]-mid*a)%b==0)tot+=(x[i]-mid*a)/b;
                  else tot+=((x[i]-mid*a)/b+1);
              }
          }
          return tot<=mid;
      }
      signed main()
      {
          cin>>n>>a>>b;
          for(int i=1;i<=n;i++)cin>>x[i];
          int l=0,r=1e9,mid;
          while(l<=r)//二分搜索 
          {
              mid=(l+r)/2;
              if(check(mid))r=mid-1;
              else l=mid+1;
          }
          cout<<l<<endl;
          return 0;
      }

      問題 E: 切巧克力:

      輸入

      4 2

      5 6

      1

      輸出

      19

      如果先切橫的,結果就是1+2?4+2?5+2?6=311+2?4+2?5+2?6=31。

      如果先切豎的,結果就是4+5+6+1?4=194+5+6+1?4=19。

      顯然先切豎的更優。

      由此,可以得出一個結論:先切代價大的。

      于是,思路就出來了。先把兩個數組從大到小排序,然后兩個數組挨個比較,較大的就在答案上加上這個代價(要乘上切了多少刀),再把指針往后挪一位,直到全部算完即可。

      #include<iostream>
      #include<cmath>
      #include<algorithm>
      using namespace std;
      int n, m;
      int a[10005], b[10005];//橫線和豎線的代價
      
      int main()
      {
          cin >> n >> m;
          int s1 = 1, s2 = 1;//s1和s2可以是a數組和b數組的指針,也可以是橫縱分成的塊數
          for (int i = 1; i <= n-1; i++)
          {
              cin >> a[i];
          }
          for (int i = 1; i <= m - 1; i++)
          {
              cin >> b[i];
          }
          for(int i=1;i<=n-1;i++)
          {
              for(int j=1;j<=n-1-i;j++)
              {
                  if(a[j]<a[j+1])
                  {
                      int t;
                      t=a[j];
                      a[j]=a[j+1];
                      a[j+1]=t;
                  }
              }
          }
          for(int i=1;i<=m-1;i++)
          {
              for(int j=1;j<=m-1-i;j++)
              {
                  if(b[j]<b[j+1])
                  {
                      int t;
                      t=b[j];
                      b[j]=b[j+1];
                      b[j+1]=t;
                  }
              }
          }
          long long ans = 0;
          for (int i = 2; i < n + m; i++)
          {
              if (a[s1] > b[s2])
                  ans += s2 * a[s1++];//選擇大的,這里s2表示塊數,s1指針后移一位
              else
                  ans += s1 * b[s2++];//同理,和上面相反
          }
          cout << ans << endl;
          return 0;
      }

      問題 F: 建房子:

      構建一個01背包。

      思路是將體力看做背包 將石子看做物品 然后就很自然地得出了本題的狀態轉移方程:

      f[j]=max(f[j],f[j-w[i]]+v[i])

      #include<stdio.h>
       #include<bits/stdc++.h>
       using namespace std;
       int n,V,c;
       int v[100001],l[100001];//v:石頭體積 l;所需的體力 
       int dp[100001];
       int main()
       {
           scanf("%d %d %d",&V,&n,&c);
           int sum=0;
           for(int i=1;i<=n;i++)
           {
               scanf("%d %d",&v[i],&l[i]);
               sum+=v[i];
           }
           if(sum<V)//若石子總體積<V 
           {
               printf("Impossible");
               return 0;
           }
           for(int i=1;i<=n;i++)
           {
               for(int j=c;j>=l[i];j--)
               {
                   dp[j]=max(dp[j],dp[j-l[i]]+v[i]);
               }
           }
           for(int i=0;i<=V;i++)//從小到大搜 第一個大于V的直接輸出
           {
               if(dp[i]>=V)
               {
                   printf("%d",c);
                   return 0;
               }
           }
           printf("Impossible");
           return 0;
       }

       

      問題 G: 命運之橋:

      此題可以用排序做(高檔一點的模擬)

      核心思想:兩個人相遇轉身,相當于交換靈魂后繼續走

      最大值:最靠近端點兩個人各自向對方走,時間較長的那個人的時間

      最小值:所有人中走完橋最小值中的最大值

      #include<iostream>
      #include<cmath>
      #include<algorithm>
      using namespace std;
      int l, a[100001];
      int main()
      {
          int n;
          scanf("%d",&l);
          scanf("%d",&n);
          if (!n)
          {
              printf("0 0\n");
              return 0;
          }
          for (int i = 1; i <= n; i++)
          {
              scanf("%d", &a[i]);
          }
          sort(a + 1, a + 1 + n); //從小到大排序(算最長時間時可能方便一些)
          int max_time, min_time;
          for (int i = 1; i <= n; i++)
          {
              min_time = max(min(a[i], l + 1 - a[i]), min_time);//最短時間就是所有人中走完橋最小值中的最大值 
          }
          max_time = max(l + 1 - a[1], a[n]);//最長時間就是最靠近端點兩個人各自向對方走,
          printf("%d %d", min_time, max_time);
          return 0;
      }

      問題 H: 惡魔:

      一個惡魔能殺掉的最大個數應該為兩側小于它血量的第一個的惡魔能殺掉的個數 + 1,先固定左側,用單調棧維護一下該側比當前惡魔更小的第一個位置,右側同理

      #include<bits/stdc++.h>
      using namespace std;
      const int N=2e5+10;
      int n;
      int a[N],l[N],r[N];
      int main()
      {
          cin>>n;
          for(int i=1;i<=n;i++) cin>>a[i];
          stack<int>s;
          for(int i=1;i<=n;i++)//左邊
          {
              while(!s.empty()&&a[s.top()]>a[i]) s.pop();
              if(!s.empty()) l[i]=l[s.top()]+1;
              else l[i]=0;
              s.push(i);
          }
          reverse(a+1,a+1+n);//反轉一次,開始做右邊
          stack<int>s1;
          for(int i=1;i<=n;i++)//右邊
          {
              while(!s1.empty()&&a[s1.top()]>a[i]) s1.pop();
              if(!s1.empty()) r[i]=r[s1.top()]+1;
              else r[i]=0;
              s1.push(i);
          }
          for(int i=1;i<=n;i++)
          {
              cout<<l[i]+r[n-i+1]<<" ";
          }
          return 0;
      }

       

      posted @ 2024-12-10 22:03  河南工業大學算法協會  閱讀(137)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 宣恩县| 国内自拍视频一区二区三区| 欧美XXXX黑人又粗又长| 情欲少妇人妻100篇| 成人一区二区三区久久精品| 午夜福利看片在线观看| 蜜臀久久99精品久久久久久| 精品少妇无码一区二区三批| 韩国福利视频一区二区三区| 肥大bbwbbw高潮抽搐| 好紧好滑好湿好爽免费视频| 亚洲区综合区小说区激情区| 国产成AV人片久青草影院| 一本色道久久加勒比综合| 亚洲午夜精品国产电影在线观看| 国产免费午夜福利在线播放| 日韩在线视频观看免费网站| 神木县| 亚洲欧洲日产国无高清码图片| 国产片AV国语在线观看手机版| 鹤庆县| 亚洲乱熟女一区二区三区| 色爱综合激情五月激情| 堆龙德庆县| 77se77亚洲欧美在线| 国产成人综合在线女婷五月99播放| 国产成人精品午夜福利| 午夜精品福利亚洲国产| 好紧好滑好湿好爽免费视频| 日本边添边摸边做边爱的网站| 激情综合网激情五月激情| 国产免费高清69式视频在线观看| 久久se精品一区精品二区国产 | 欧美裸体xxxx极品| 久久精品丝袜高跟鞋| 日韩精品一区二区都可以| аⅴ天堂中文在线网| 人妻伦理在线一二三区| 亚洲熟伦熟女新五十熟妇| 久久一日本道色综合久久| 少妇人妻真实偷人精品|