首页 > 试题广场 >

元素方碑

[编程题]元素方碑
  • 热度指数:12084 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解


\hspace{15pt}菲谢尔在稻妻冒险途中遇到一排神奇的元素方碑,其中第 i 个方碑初始时的能量为 a_i。只要她对第 i 块方碑施放雷元素,就会发生能量转移:

\hspace{23pt}\bullet\,正面轰击:雷元素从第 i-1 块流向第 i+1 块,使 a_{i-1}1a_{i+1}1
\hspace{23pt}\bullet\,反面轰击:雷元素从第 i+1 块流向第 i-1 块,使 a_{i+1}1a_{i-1}1

\hspace{15pt}操作只能在 2\leqq i\leqq n-1 的方碑上进行,且任何时刻所有方碑能量 a_{i} 必须保持非负。
\hspace{15pt}当所有方碑的能量 a_1,a_2,\dots,a_n 全部相等时,菲谢尔即可开启隐藏宝箱。
\hspace{15pt}菲谢尔可以无限次进行操作。请判断,她是否一定能够让所有方碑能量相等。

输入描述:
\hspace{15pt}第一行输入一个整数 t\left(1\leqq t\leqq 10^4\right)——测试用例组数。 
\hspace{15pt}对于每组测试数据:
\hspace{23pt}\bullet\,第一行输入一个整数 n\left(1\leqq n\leqq 2\times10^5\right)——方碑数量;
\hspace{23pt}\bullet\,第二行输入 n 个整数 a_1,a_2,\dots,a_n\left(1\leqq a_i\leqq 10^9\right)——初始能量。

\hspace{15pt}除此之外,保证单个测试文件中全部测试用例的 n 之和不超过 2\times10^5


输出描述:
\hspace{15pt}对每组测试数据,在一行上输出 \texttt{YES}\texttt{NO},表示能否通过若干次操作使所有方碑能量相等。
示例1

输入

8
3
3 2 1
3
1 1 3
4
1 2 5 4
4
1 6 6 1
5
6 2 1 4 2
4
1 4 2 1
5
3 1 2 1 3
3
2 4 2

输出

YES
NO
YES
NO
YES
NO
NO
NO

说明

\hspace{15pt}在第一组样例中: 
\hspace{23pt}\bullet\,对于数组 \{3,2,1\},先对下标 i=2 正面轰击一次,得到 \{2,2,2\},能量已全部相等;
\hspace{23pt}\bullet\,对于数组 \{1,2,5,4\},可依次正面轰击 i=3,反面轰击 i=2,最终得到 \{3,3,3,3\}
\hspace{23pt}\bullet\,对于数组 \{2,4,2\},无论如何操作,总能量 \sum a_i 不是 n 的倍数,因此无法全等,答案为 \texttt{NO}
列表分成两组,一组为奇数项,一组为偶数项,奇数项偶数项长度都大于0,不然列表是单个元素,直接YES
要满足两个条件,奇数项均值等于偶数项均值,且所有总和的均值为整数才能得到结果
其余均不可。
发表于 2025-07-14 15:35:30 回复(0)
这道题需要抓住的就是能量的传递过程,显然对当前i方碑操作,能量传递是从i-1到i+1,并不会改变当前方碑的能量,这说明奇数(下标)方碑的能量只会在奇数方碑间传递,偶数方碑的能量只会在偶数(下标)方碑间传递
所以对于要求所有的方碑能量相等:
第一个条件:单个方碑的平均能量(总能量除以方碑数量)必须为整数。
第二个条件:对总序列拆分,拆分为奇数和偶数两个序列,偶数序列的平均能量必须和奇数序列的平均能量相等
发表于 2026-01-22 15:13:47 回复(0)
我没看懂题,它的示例和我对能量转移过程的理解,完全对不上
发表于 2025-11-05 17:49:47 回复(1)
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int round = in.nextInt();

        for (int i = 0; i < round; i++) {
            int n = in.nextInt(); // 表示方碑数量
            long oddSum = 0;     
            long evenSum = 0;     

            result: {
                // 处理n=1的边界情况:单个方碑已相等
                if (n == 1) {
                    in.nextLong();
                    System.out.println("YES");
                    break result;
                }

                // 读取n个方碑的能量,按1-based索引分奇偶位求和
                for (int j = 1; j <= n; j++) {
                    long num = in.nextLong(); 
                    if (j % 2 == 1) {
                        oddSum += num;
                    } else {
                        evenSum += num;
                    }
                }

                // 条件1:总能量必须能被n整除(否则无法均分)
                long total = oddSum + evenSum;
                if (total % n != 0) {
                    System.out.println("NO");
                    break result;
                }

                // 计算奇位数量和偶位数量
                int oddCount = (n + 1) / 2; // 1-based索引的奇位数量(如n=3→2,n=4→2)
                int evenCount = n / 2;      // 1-based索引的偶位数量(如n=3→1,n=4→2)

                // 条件2:奇位总和/奇位数量 == 偶位总和/偶位数量(均等于avg)
                // 注:因total%n==0,且oddSum/oddCount == evenSum/evenCount,故必能整除(推导见前文)
                if (oddSum / oddCount == evenSum / evenCount) {
                    System.out.println("YES");
                } else {
                    System.out.println("NO");
                }
            }
        }
        in.close();
    }
}

发表于 2025-08-27 20:57:51 回复(0)
#include <iostream>
using namespace std;

int main() {
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        int q1 = 0, q2 = 0; //分母
        int p1 = 0, p2 = 0; //分子
        if (n == 1){cout << "YES" << endl;cin>>n;}
        else {
            for (int i = 0; i < n; i++) {
                int in;
                cin >> in;
                if (i % 2) {
                    q1++;
                    p1 += in;
                } else {
                    q2++;
                    p2 += in;
                }
            }
            if (p1 / q1 == p2 / q2 && p1 % q1 == 0 && p2 % q2 == 0) {
                cout << "YES" << endl;
            } else {
                cout << "NO" << endl;
            }
        }
    }
}


发表于 2026-04-13 16:44:33 回复(0)
import sys

t = int(sys.stdin.readline())
for _ in range(t):
    n, a = int(sys.stdin.readline()), list(map(int, sys.stdin.readline().split()))
    if sum(a) % n == 0:
        s = sum(a[i] for i in range(1, n, 2))
        print("YES" if s == sum(a) // n * (n // 2) else "NO")
    else:
        print("NO")

发表于 2026-01-21 18:46:39 回复(0)
执行出错
程序异常退出, 请检查代码"是否有数组越界等异常"或者"是否有语法错误"
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at Main.main(Main.java:15)
测试样例输入有问题,使用 import java.util.* 会报错好像
发表于 2026-04-13 21:03:16 回复(0)
#include <bits/stdc++.h>
using namespace std;
using ll=long long;

int main() 
{
    int t;
    cin>>t;
    while (t--)
    {
        int n;
        cin>>n;
        vector<ll> a,b;
        ll all=0,t;
        ll all_a=0,all_b=0;

        for (ll i=0;i<n;i++) 
        {
            cin>>t;
            all+=t;
            if (i&1) 
            {
                b.push_back(t);
                all_b+=t;
            }
            else 
            {
                a.push_back(t);
                all_a+=t;
            }
        }

        ll target=all/n;
        if (all%n!=0) 
        {
            cout<<"NO\n";
            continue;
        }
        else if (a.size()>0 && target*a.size()!=all_a)
        {
            cout<<"NO\n";
            continue;        
        }
        else if (b.size()>0 && target*b.size()!=all_b)
        {
            cout<<"NO\n";
            continue;
        }
        else 
        {
            cout<<"YES\n";
            continue;
        }
    }
}
// 64 位输出请用 printf("%lld")

发表于 2026-04-13 19:56:09 回复(0)
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define debug(x) cerr << #x << ": " << x << '\n';
const int INF = 0x3f3f3f3f3f3f3f3f;
void solve(){
    int n;
    cin >> n;
    int sum1 = 0, sum2 = 0;
    for(int i = 1;i <= n; ++i){
        int x;
        cin >> x;
        if(i & 1LL) sum1 += x;
        else sum2 += x;
    }
    if(n == 1){
        cout<<"YES\n";
        return;
    }
    if(sum1 % ((n+1)/2) == 0 && sum2 % (n/2) == 0 && sum1 / ((n+1)/2) == sum2 / (n/2)){
        cout<<"YES\n";
    }
    else cout<<"NO\n";
}
signed main(){
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int t = 1;
    cin >> t;
    while(t--){
        solve();
    }return 0;
}

发表于 2026-04-13 12:21:33 回复(0)
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int t = in.nextInt();
        for (int i = 0; i < t; i++) {
            int n = in.nextInt();
            long sum = 0;
            int even = 0, odd = 0;
            long[] a = new long[n];
            for (int i1 = 0; i1 < n; i1++) {
                a[i1] = Long.parseLong(in.next());
                sum += a[i1];//计算所有位的合
                if (i1 % 2 == 0) odd += a[i1];//奇数位和
                else even += a[i1];//偶数位和
            }
            if (sum % n != 0) System.out.println("NO");//若所有位和不是n的倍数,输出NO
            else if (n==1||(even / (n / 2)) == (odd / (n / 2 + n % 2))) System.out.println("YES");//若平均奇数位和平均偶数位相等,满足要求
            else System.out.println("NO");//其他条件都不满足
        }
    }
}
发表于 2026-04-12 19:55:09 回复(0)
原神,启动!
发表于 2026-03-06 16:26:22 回复(0)
using System;
using System.Collections.Generic;
public class Program {
    public static void Main() {
        string line = System.Console.ReadLine();
        int n =int.Parse(line);
        for(int i=0;i<n;++i){
            slov();
        }


    }
    static void slov(){
        string line =System.Console.ReadLine();
        int n= int. Parse(line);
        line =System.Console.ReadLine();
        string[] parts =line.Split( );
        long [] a =new long[n];
        long sum=0;
        for(int i=0;i<n;++i){
            a[i] = long.Parse(parts[i]);
            sum+=a[i];
        }
        if(sum%n !=0){
            System.Console.WriteLine("NO");
            return;
        }
        long avg= sum/n;
        long diffsum=0;
        for(int i=0;i<n;i+=2){
            diffsum+= a[i] -avg;

        }
        if(diffsum == 0){
            System.Console.WriteLine("YES");
        }
        else{
            System.Console.WriteLine("NO");
        }


    }
}

发表于 2026-02-25 15:53:00 回复(0)
#include <iostream>
using namespace std;
#include <vector>

int main(){
    int N;
    cin >> N;
    for(int i = 0; i < N; ++i){
        vector<long long> v1, v2;
        int n;
        cin >> n;
        long long count = 0;
        long long count1 = 0, count2 = 0;
        for(int j = 1; j <= n; ++j){
            long long num;
            cin >> num;
            count += num;
            if(j % 2 != 0){
                v1.push_back(num);
                count1 += num;
            }
            else{
                v2.push_back(num);
                count2 += num;
            }
        }
        if(count % n != 0) cout << "NO" << endl;
        else{
            long long avg = count / n;
            if(avg * v1.size() == count1 && avg * v2.size() == count2){
                cout << "YES" << endl;
            }
            else cout << "NO" << endl;
        }
    }
    return 0;
}

发表于 2026-02-05 06:44:07 回复(0)
#include <stdio.h>
int main(){
    int t;
    scanf("%d",&t);
    while(t)
    {
        int n;
        scanf("%d",&n);
        int a[n];
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        int j=0,o=0,j_sum=0,o_sum=0;
        if(n==1){
            printf("YES\n");
            t--;
        }
        else
        {
           for(int i=0;i<n;i++)
           {
                  if(i%2==0)
                  {
                     j++;
                     j_sum+=a[i];
                  }
                  else
                  {
                     o++;
                     o_sum+=a[i];
                  }
             }
            if(j_sum/j==o_sum/o&&j_sum%j==0&&o_sum%o==0)
                 printf("YES\n");
            else
                 printf("NO\n");    
            t--;
        }
    }    
}
发表于 2026-02-04 14:11:39 回复(0)
#include <iostream>
using namespace std;
#include<vector>

int main() {
   int T;
   cin>>T;
   while(T--){ 
     int n;
     int n_ji=0,n_ou=0;
     cin>>n;
     vector<long long>v;
     for(int i=0;i<n;i++){
        long long a;
        cin>>a;
         v.push_back(a);
     }
     long long sum=0;
     long long jisum=0,ousum=0;
     long long av=0,av_ji=0,av_ou=0;
     for(int i=0;i<v.size();i++){
             sum+=v[i];
          if(i%2==0){
             n_ou++;
             ousum+=v[i];
          }
          if(i%2!=0){
             n_ji++;
             jisum+=v[i];
           }
     }
          
        if(n_ji==0){//当只有一块的时候 防止0除法报错 提前判断
            cout<<"YES"<<endl;
        }
       else if(sum%n!=0){
        cout<<"NO"<<endl;
       }
 else if(ousum/n_ou!=sum/n||ousum%n_ou!=0){//偶数元素不能整除  偶数平均值不等于平均值
           cout<<"NO"<<endl;
       }
else if(jisum/n_ji!=sum/n||jisum&n_ji!=0){//奇数元素不能整除  奇数平均值不等于平均值
        cout<<"NO"<<endl;                             
       }
else{
        cout<<"YES"<<endl;
      }
       
     

    //  av=sum/n;
    //  av_ou=ousum/n_ou;
    //  av_ji=jisum/n_ji;
   }
}

发表于 2026-01-14 20:40:09 回复(0)
# 所有的能量只能在隔一个方尖碑上流动。1,3,5,7... / 2,4,6,8...
# 并且可以操作任意次,每次加减1,所以只要保证整个数组的和是n的倍数,并且上面两组的平均数相等
# 先判断所有和是否是n倍数。
g = int(input())
for _ in range(g):
    n = int(input())
    l = list(map(int,input().split()))
    if (len(l) == 1):
        print("YES")
        continue
    elif (sum(l) % n):
        print("NO")
        continue
    else:
        l1 = [x for i,x in enumerate(l) if i % 2 == 0]
        l2 = [x for i,x in enumerate(l) if i % 2 == 1]
        if (sum(l1)/len(l1) == sum(l2)/len(l2)):
            print("YES")
            continue
        else:
            print("NO")
            continue
发表于 2025-11-30 10:57:44 回复(0)
奇偶组平均相等即可
import sys
def main():
    t=int(input())
    for _ in range(t):
        n=int(input())
        arr=list(map(int,input().split()))
        if sum(arr)%n !=0:
            print("NO")
            continue
        odd=arr[1::2]
        even=arr[0::2]
        if len(odd) and len(even):
            if (sum(odd)/len(odd))!=(sum(even)/len(even)):
                print("NO")
                continue
        print("YES")
if __name__=="__main__":
    main()

发表于 2025-09-25 23:07:06 回复(0)
import sys

t = int(input())
for _ in range(t):
    n = int(input())
    num_list = list(map(int, input().split()))

    if len(num_list) <= 1:
        print('YES')
    elif sum(num_list) % len(num_list) != 0:
        print('NO')
    else:
        num_list1, num_list2 = num_list[0::2], num_list[1::2]
        if sum(num_list1) / len(num_list1) != sum(num_list2) / len(num_list2):
            print('NO')
        else:
            print('YES')
   
   
发表于 2025-09-18 17:19:44 回复(0)
#include <iostream>
#include<vector>
using namespace std;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int t, n;
    cin >> t;
    while (t--) {
        cin >> n;
        long long sum = 0;
        vector<int> vec(n);
        for (int i = 0; i < n; i++) {
            cin >> vec[i];
            sum += vec[i];
        }
        if (sum % n != 0) {
            cout << "NO\n";
            continue;
        }
        long long av = sum / n;
        for (int i = 1; i < n - 1; i++) {
            vec[i + 1] += vec[i - 1] - av;
            vec[i - 1] = av;
        }
        if (vec[n - 1] != av)
            cout << "NO\n";
        else
            cout << "YES\n";
    }
}

发表于 2025-09-14 14:05:25 回复(0)
#include <cstddef>
#include <iostream>
using namespace std;
#include <cstdlib>
#include <vector>
#include <sstream>

int main() {
    int t, n;
    string s;
    cin >> t;
    while (t--) { // 注意 while 处理多个 case
        vector<int> v;
        v.clear();
        cin >> n;
        cin.ignore();
        getline(cin, s);
        istringstream ss(s);
        int sum = 0;
        while(getline(ss, s, ' ')){
            v.push_back(stoi(s));
            sum += stoi(s);
        }
        if(sum % n != 0){
            cout << "NO" << endl;
            continue;
        }
        sum /= n;
        for(int i = 0; i < n - 2; i++){
            v[i + 2] -= sum - v[i];
            v[i] = sum;
        }
        bool b = true;
        for(auto p:v){
            if(p != sum){
                cout << "NO" << endl;
                b =false;
                break;
            }
        }
        if(b){
            cout << "YES" << endl;
        }
    }
}
// 64 位输出请用 printf("%lld")
发表于 2025-08-27 15:30:24 回复(0)