11 条题解

  • 1
    @ 2024-9-16 18:32:16

    J1A. 『FLA - III』Spectral

    思路

    模拟。当火焰的温度相同时,跳出循环并输出答案。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int T, n;
    double k, t, p;
    
    int main()
    {
    	scanf("%d", &T);
    	while (T -- )
    	{
    		t = 0;
    		scanf("%d %lf", &n, &k);
    		for (int i = 1; i <= n; i ++ )
    		{
    			p = t;
    			t = max(t, k + t / i);
    			if (p == t)
    				i = n;
    		}
    		printf("%.1lf\n", t);
    	}
    	return 0;
    }
    
    • 0
      @ 2024-7-26 14:34:07

      J1A 题解

      第二篇题解。

      此题按照题意模拟,当两次火焰的温度相同时即可跳出循环并输出答案。

      代码:

      #include<iostream>
      using namespace std;
      int main()
      {
          int t;
          cin>>t;
          while(t--)
          {
              int n;
              double k,t=0;
              cin>>n>>k;
              for(int i=1;i<=n;i++)
              {
                  double p=t;
                  t=max(t,k+t/i);
                  if(p==t)i=n;
              }
              printf("%.1lf\n",t);
          }
          return 0;
      }
      
      • -1
        @ 2024-7-26 21:32:21

        题解

        思路

        这题只需根据题目递推关系式,找规律即可

        解题方法

        我们从 n=0n=0 开始计算

        T0=0T_0=0

        T1=kT_1=k

        T2=k+T1/2=3/2×kT_2=k+T_1/2=3/2 \times k

        T3=k+T2/3=3/2×kT_3=k+T_2/3=3/2 \times k

        T4=k+T3/4=3/8×k=(3/(2×4))×kT_4=k+T_3/4=3/8 \times k=(3/(2 \times 4))\times k

        $T_5=k+T_4/5=3/40 \times k=(3/(2 \times 4 \times 5))\times k$

        $T_6=k+T_5/6=3/240 \times k=(3/(2 \times 4 \times 5 \times 6))\times k$

        我们设 x=3/2kx =3/2k

        T0=0T_0=0

        T1=1T_1=1

        T2=xT_2=x

        T3=xT_3=x

        Tn=(x×(4×5×6...×n))kT_n=(x \times (4 \times 5 \times 6 ... \times n))k

        众所周知,随着 nn 的变化, (4×5×6...×n))(4 \times 5 \times 6 ... \times n)) 越来越大,也就是除数越来越大.

        而被除数不变,除数变大,商也就越来越小,即 TnT_n 越来越小 .

        可以看出,除 T2T_2T3T_3 不变,其余 TnT_n 的趋势为越来越小.

        又因为 3/2×k>k3/2 \times k > k ,即 T2>T1T_2>T_1

        所以,当 n=1n=1 时,只能取 T0T_0T1T_1.

        因为 T0=0T_0=0 , T1=kT_1=k , k>0k>0

        所以 T1>T0T_1>T_0

        所以取 T1T_1 , 即 kk .

        否则,即 n>=2n>=2时.

        因为除 T2T_2T3T_3 不变,其余 TnT_n 的趋势为越来越小.

        所以 n>=2n>=2 时,答案取 T2T_2T3T_3 时最大,即 3/2×k3/2 \times k .

        时间复杂度:

        添加时间复杂度, 示例: O(1)O(1)

        空间复杂度:

        添加空间复杂度, 示例: O(1)O(1)

        Code

        #include <bits/stdc++.h>
        using namespace std;
        int main()
        {
            int t;
            cin>>t;
            while(t--)
            {
                int n;
                cin>>n;
                double k;
                cin>>k;
                double ans=k*3/2*1.00; //保留精度
                if(n!=1) printf("%.1lf\n",ans);
                else printf("%.1lf\n",k); //特殊情况
            }
            return 0;
        }
        
        • -2
          @ 2024-7-15 15:33:07

          赛时用实时更新最大值并判断的方法通过了此题,现在证明一下这个算法的时间复杂度。

          首先,我们可以将 T1TnT_1 \sim T_n 都表示为 (1+pq)k(1 + \frac{p}{q})k 的形式,T1T_1 显然是 kkT2T_2 通过推导可得 (1+12)k=32k(1 + \frac{1}{2})k = \frac{3}{2}k。随着 ii 的增加,qq 也随之增加,那么 TiT_i 也会变得越来越小。对于 ii2n2 \sim n 中的 TiT_i,我们就有 T2T3T4T5TnT_2 \ge T_3 \ge T_4 \ge T_5 \ge \ldots \ge T_n,实际上从 T3T_3 开始就已经满足严格单调递减了,所以这个算法最多会执行 33 次,时间复杂度显然是 O(1)O(1)

          参考代码如下:

          // #pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
          #define _CRT_SECURE_NO_WARNINGS
          #include <bits/stdc++.h>
          #define ll long long
          #define writes(x) write(x), putchar(' ')
          #define writeln(x) write(x), putchar('\n');
          static char buf[100000], * pa(buf), * pb(buf);
          int st[114], top;
          #define gc pa == pb && (pb = (pa = buf) + fread(buf, 1, 100000, stdin), pa == pb) ? EOF : *pa++
          using namespace std;
          mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
          void debug(auto st, auto ed, bool endline) {
          	for (auto it = st; it != ed; ++it) {
          		cout << *it << " ";
          	}
          	if (endline) cout << '\n';
          }
          template <typename T> void read(T& x) {
          	T t = 0, sgn = 1;
          	char ch = gc;
          	while (!isdigit(ch)) {
          		if (ch == '-') sgn = -sgn;
          		ch = gc;
          	}
          	while (isdigit(ch)) {
          		t = (t << 3) + (t << 1) + (ch ^ 48);
          		ch = gc;
          	}
          	x = sgn * t;
          }
          template <typename T, typename ...Args> void read(T& tmp, Args &...tmps) {
          	read(tmp); read(tmps...);
          }
          template <typename T> void write(T x) {
          	if (x < 0) putchar('-'), x = -x;
          	top = 0;
          	while (x) {
          		st[++top] = x % 10;
          		x /= 10;
          	}
          	do {
          		putchar(st[top--] + '0');
          	} while (top > 0);
          }
          template <typename T, typename ...Args> void write(T& tmp, Args &...tmps) {
          	writes(tmp);
          	writes(tmps...);
          }
          template <typename T> T rand(T l, T r) {
          	return rnd() % (r - l + 1) + l;
          }
          int main() {
          	cin.tie(0)->sync_with_stdio(0);
          	cout.tie(0)->sync_with_stdio(0);
          	int t;
          	cin >> t;
          	while (t--) {
          		ll n, k;
          		cin >> n >> k;
          		double ans = 0.0;
          		double mxn = 0.0;
          		for (int i = 1; i <= n; i++) {
          			ans = (1.0 * k + 1.0 * ans / i);
          			if (ans > mxn) {
          				mxn = ans;
          			}
          			else break;
          		}
          		cout << fixed << setprecision(1) << mxn << '\n';
          	}
          }
          
          • -2
            @ 2024-7-14 20:23:17

            模拟、数学


            测试点 121 \sim 2

            容易得到在 n=1n=1 时答案为 kk,在 n=2n=2 时答案为 1.5k1.5k

            测试点 343 \sim 4

            暴力计算 T1TnT_1 \sim T_n 后取最大值。

            测试点 55

            ii 00 11 22 33 44 55 \cdots
            TiT_i 00 kk 1.5k1.5k 1.375k1.375k 1.275k1.275k \cdots

            序列 TT 的最大值是 T2T_2T3T_3,读者可以自行查看题解结尾处的证明。

            n=1n=1 时答案为 kk,否则答案为 1.5k1.5k

            单组数据时间复杂度 O(1)O(1)

            #include<bits/stdc++.h>
            using namespace std;
            int T,n,k;
            int main(){
                scanf("%d",&T);
                while(T--){
                    scanf("%d%d",&n,&k);
                    if(n==1) printf("%d.0\n",k);
                    else if(k%2==0) printf("%d.0\n",k+k/2);
                    else printf("%d.5\n",k+k/2);
                }
                return 0;
            }
            

            证明:若 Ti>Ti+1T_i > T_{i+1},由于 Ti+1=k+Tii+1T_{i+1}=k+ \dfrac{T_i}{i+1}Ti+2=k+Ti+1i+2T_{i+2}=k+ \dfrac{T_{i+1}}{i+2},那么 $T_{i+2}-T_{i+1}=\dfrac{T_{i+1}}{i+2}- \dfrac{T_i}{i+1}<0$,因为 Ti+1i+2\dfrac{T_{i+1}}{i+2} 的分母更大,分子更小。

            因为 Ti+2Ti+1<0T_{i+2}-T_{i+1}<0,所以 Ti+1>Ti+2T_{i+1}>T_{i+2},又因为 Ti+1>Ti+2T_{i+1}>T_{i+2} 所以 Ti+2>Ti+3T_{i+2}>T_{i+3}。以此类推,只要存在 Ti>Ti+1T_i > T_{i+1},那么对于所有大于 ii 的整数 jj 都有 Ti>TjT_i > T_j,又因为 T3>T4T_3 > T_4,所以序列 TT 的最大值只可能在 T1,T2,T3T_1,T_2,T_3 中取到,可知序列 TT 的最大值为 T2=T3=1.5kT_2=T_3=1.5k

          • -3
            @ 2024-9-25 23:24:12

            J1A 题解

            思路

            通过找规律,发现:

            • n=0n = 0 时,答案为 0.00.0
            • n=1n = 1 时,答案为 kk
            • n>1n > 1 时,答案为 1.5k1.5k

            复杂度

            时间复杂度:

            O(1)O(1)

            空间复杂度:

            O(1)O(1)

            Code

            #include <bits/stdc++.h>
            int main() 
            {
                int _t; std::cin >> _t;
                for(; _t; --_t) 
                {
                    long double n, k;
                    std::cin >> n >> k;
                    long double ans;
                    if(n == 0) ans = 0;
                    else if(n == 1) ans = k;
                    else ans = 1.5 * k;
                    std::cout << std::fixed << std::setprecision(1) << ans << '\n';
                }
            }
            
            • -3
              @ 2024-8-3 14:27:14

              J1A题解

              40分思路

              暴力解决

              复杂度

              时间复杂度: O(Tn)O(Tn),空间复杂度: O(1)O(1)

              Code

              #include <bits/stdc++.h>
              using namespace std;
              int i, j, k, n, T; double C;
              int main() {
                  scanf("%d", &T);
                  for (i = 1; i <= T; i++) {
                      scanf("%d %d", &n, &k);
                      for (j = 1; j <= n; j++) C = C / j + k;
                      printf("%.1lf\n", C);
                  }
                  return 0;
              }
              

              喜提TLE

              80分思路

              还是暴力,只不过加一个最大值

              复杂度

              时间复杂度: O(Tn)O(Tn),空间复杂度: O(1)O(1)

              Code

              #include <bits/stdc++.h>
              using namespace std;
              int i, j, k, n, T; double C, c;
              int main() {
                  scanf("%d", &T);
                  for (i = 1; i <= T; i++) {
                      scanf("%d %d", &n, &k);
                      for (j = 1; j <= n; j++) c = C / j + k, C = max(C, c);
                      printf("%.1lf\n", C);
                  }
                  return 0;
              }
              

              又双叒叕敠敪喜提TLE

              100分思路

              打一个表,发现如下规律:
              |T1T_1|T2T_2|T3T_3|T4T_4|T5T_5| |-----|-----|-----|-----|-----| |kk|32k\frac{3}{2}k|32k\frac{3}{2}k|118k\frac{11}{8}k|5140k\frac{51}{40}k|

              整个序列 {Tn}\{T_n\} 的峰值在 T2T_2T3T_3

              复杂度

              时间复杂度: O(T)O(T),空间复杂度: O(1)O(1)

              Code

              #include <bits/stdc++.h>
              using namespace std;
              int i, k, n, T;
              int main() {
                  scanf("%d", &T);
                  for (i = 1; i <= T; i++) {
                      scanf("%d %d", &n, &k);
                      if (n == 1) printf("%d.0\n", k);
                      else if (k & 1) printf("%d.5\n", k + k / 2);
                      else printf("%d.0\n", k + k / 2);
                  }
                  return 0;
              }
              

              终于AC了

              • -3
                @ 2024-7-30 10:37:15

                Code

                
                #include<bits/stdc++.h>
                using namespace std;
                int main()
                {
                    int t;
                    cin>>t;
                    while(t--)
                    {
                        int n;
                        double k,t=0;
                        cin>>n>>k;
                        for(int i=1;i<=n;i++)
                        {
                            double p=t;
                            t=max(t,k+t/i);
                            if(p==t)i=n;
                        }
                        printf("%.1lf\n",t);
                    }
                    return 0;
                }
                ...
                • @ 2024-7-31 14:43:53

                  你代码和我的好像啊(

              • -3
                @ 2024-7-15 14:17:25

                由于此题 t,n,kt,n,k 都很(hen)大,所以易得是奇思妙想题。

                打个表 : |烧炭数ii |TiT_i | |:---:|:---:| |00|00| |11|kk| |22|1.5k1.5k| |33|1.5k1.5k| |44|1.375k1.375k| 容易发现,TiT_i 在烧2块时达到峰值

                所以直接算,特判 n=1n=1 就行

                代码如下:

                #include<bits/stdc++.h>
                using namespace std;
                double ans,f; 
                signed main(){
                	int t,n,k;
                	scanf("%d",&t);
                	while(t--){
                		scanf("%d%d",&n,&k);
                		ans=0;f=0;
                		if(n<2)ans=k;
                		else ans=1.5*k; 
                		printf("%.1lf\n",ans);
                	} 
                	return 0; 
                } 
                
                • -3
                  @ 2024-7-15 7:44:57

                  P10781 【MX-J1-T1】『FLA - III』Spectral 题解

                  大致思路:

                  这道题目最直接的方法就是暴力找最大值,显然会超时,接着就是进行打表,我们会发现,这道题的函数,是一个单峰函数,只会在一开始持续上升,在一定的位置持续下降,所以我们只需要找到那个转折点,直接退出即可。

                  代码实现:

                  #include <bits/stdc++.h>
                  #define int long long
                  using namespace std;
                  const int MOD = 1e9 + 7;
                  const int N = 5e5 + 10;
                  inline int read()
                  {
                      int x = 0, f = 1; char ch = getchar();
                      while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
                      while (isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); }
                      return x * f;
                  }
                  int T;
                  signed main() {
                  	T = read();
                      while (T--) {
                          double k, res = 0;
                          int n;
                          n = read();
                          cin >> k;
                          if(n == 1) cout << fixed << setprecision(1) << k << "\n";
                          else{
                  			for (int i = 1;i <= n; ++ i)
                  			{
                  				if(k + res / i < res) break;
                  				else res = k + res / i;
                  			}
                  			cout << fixed << setprecision(1) << res << "\n";
                          }
                      }
                      return 0;
                  }
                  

                  这样这道题目就完成啦!!!

                  • -12
                    @ 2024-7-26 8:24:24

                    标题 P10781 【MX-J1-T1】『FLA - III』Spectral 题解

                    大致思路:

                  • 1

                  信息

                  ID
                  13
                  时间
                  1000ms
                  内存
                  512MiB
                  难度
                  2
                  标签
                  递交数
                  1259
                  已通过
                  336
                  上传者