SWUST OJ 2540 少女输出问题

本文介绍了一道关于快速傅立叶变换(FFT)的算法题目,并提供了完整的代码实现。通过本例,读者可以了解到FFT的基本原理及其在多项式乘法等场景中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:见这里
题意: 中文题目, FFT裸题。
代码如下:

//
//Created by BLUEBUFF 2016/1/11
//Copyright (c) 2016 BLUEBUFF.All Rights Reserved
//

#pragma comment(linker,"/STACK:102400000,102400000")
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//#include <ext/pb_ds/hash_policy.hpp>
//#include <bits/stdc++.h>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdio>
#include <time.h>
#include <cstdlib>
#include <cstring>
#include <complex>
#include <sstream> //isstringstream
#include <iostream>
#include <algorithm>
using namespace std;
//using namespace __gnu_pbds;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, LL> pp;
#define REP1(i, a, b) for(int i = a; i < b; i++)
#define REP2(i, a, b) for(int i = a; i <= b; i++)
#define REP3(i, a, b) for(int i = a; i >= b; i--)
#define CLR(a, b)     memset(a, b, sizeof(a))
#define MP(x, y)      make_pair(x,y)
template <class T1, class T2>inline void getmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void getmin(T1 &a, T2 b) { if (b<a)a = b; }
const int maxn = 270010;
const int maxm = 1e5+5;
const int maxs = 10;
const int maxp = 1e3 + 10;
const int INF  = 1e9;
const int UNF  = -1e9;
const int mod  = 1e9 + 7;
const int rev = (mod + 1) >> 1; // FWT
const double PI = acos(-1);
//head

struct FastIO
{
    static const int S = 1310720;
    int wpos;
    char wbuf[S];
    FastIO() : wpos(0) {}
    inline int xchar()
    {
        static char buf[S];
        static int len = 0, pos = 0;
        if (pos == len)
            pos = 0, len = fread(buf, 1, S, stdin);
        if (pos == len) return -1;
        return buf[pos ++];
    }
    inline int xuint()
    {
        int c = xchar(), x = 0;
        while (c <= 32) c = xchar();
        for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
        return x;
    }
    inline int xint()
    {
        int s = 1, c = xchar(), x = 0;
        while (c <= 32) c = xchar();
        if (c == '-') s = -1, c = xchar();
        for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
        return x * s;
    }
    inline void xstring(char *s)
    {
        int c = xchar();
        while (c <= 32) c = xchar();
        for (; c > 32; c = xchar()) * s++ = c;
        *s = 0;
    }
    inline void wchar(int x)
    {
        if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0;
        wbuf[wpos ++] = x;
    }
    inline void wint(LL x)
    {
        if (x < 0) wchar('-'), x = -x;
        char s[24];
        int n = 0;
        while (x || !n) s[n ++] = '0' + x % 10, x /= 10;
        while (n--) wchar(s[n]);
    }
    inline void wstring(const char *s)
    {
        while (*s) wchar(*s++);
    }
    ~FastIO()
    {
        if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;
    }
} io;

typedef complex <double> Complex;

void rader(Complex *y, int len) {
    for(int i = 1, j = len / 2; i < len - 1; i++) {
        if(i < j) swap(y[i], y[j]);
        int k = len / 2;
        while(j >= k) {j -= k; k /= 2;}
        if(j < k) j += k;
    }
}
void fft(Complex *y, int len, int op) {
    rader(y, len);
    for(int h = 2; h <= len; h <<= 1) {
        double ang = op * 2 * PI / h;
        Complex wn(cos(ang), sin(ang));
        for(int j = 0; j < len; j += h) {
            Complex w(1, 0);
            for(int k = j; k < j + h / 2; k++) {
                Complex u = y[k];
                Complex t = w * y[k + h / 2];
                y[k] = u + t;
                y[k + h / 2] = u - t;
                w = w * wn;
            }
        }
    }
    if(op == -1) for(int i = 0; i < len; i++) y[i] /= len;
}

int n, m, x;
Complex x1[maxn], x2[maxn];

int main()
{
    //scanf("%d%d", &n, &m);
    n = io.xint();
    m = io.xint();
//    REP1(i, 0, n) a[i] = io.xint();
//    REP1(i, 0, m) b[i] = io.xint();
    int len = 1;
    while(len < n * 2 || len < m * 2) len <<= 1;
    REP1(i, 0, n){
        x = io.xint();
        x1[i] = Complex(x, 0);
    }
    REP1(i, n, len) x1[i] = Complex(0, 0);
    REP1(i, 0, m){
        x = io.xint();
        x2[i] = Complex(x, 0);
    }
    REP1(i, m, len) x2[i] = Complex(0, 0);
    fft(x1, len, 1);
    fft(x2, len, 1);
    REP1(i, 0, len) x1[i] = x1[i] * x2[i];
    fft(x1, len, -1);
    len = n + m - 1;
    for(int i = 0; i < len - 1; i++) printf("%d ", (int) (x1[i].real() + 0.5));
    printf("%d\n", (int) (x1[len - 1].real() + 0.5));
    return 0;
}
### SWUST OJ 794 题目分析 SWUST OJ 794 的题目通常涉及动态规划或贪心算法的应用。虽然具体题目未提供,但从常见的题型来看,这类问题可能围绕背包问题、序列优化或其他经典的组合优化模型展开。 #### 动态规划的核心思想 动态规划是一种通过分解子问题并保存中间结果来解决复杂问题的方法。其核心在于定义状态转移方程以及初始化条件。例如,在引用中的买家问题中,状态转移方程被定义为: \[ a[i][v] = \max(a[i-1][v], a[i-1][v-w[i]]+c[i]) \] 这表示当前状态下最优解由前一状态的最大值决定,或者从前一状态减去物品重量后的价值加上当前物品的价值得到[^1]。 如果 SWUST OJ 794 是类似的背包问题,则可以采用相似的状态转移逻辑。假设 \( dp[j] \) 表示容量为 \( j \) 时能获得的最大收益,那么状态转移方程可能是: \[ dp[j] = \max(dp[j], dp[j - weight[i]] + value[i]) \] 其中 \( weight[i] \) 和 \( value[i] \) 分别代表第 \( i \) 件商品的重量和价值。 --- #### 贪心策略的可能性 另一种常见方法是贪心算法。如果 SWUST OJ 794 属于区间覆盖、活动安排等问题,则可以通过局部最优选择实现全局最优。例如,引用中的 Coin-row Problem 使用了贪心的思想,即每次取两个连续位置之间的较大值作为下一步的选择依据[^2]。 对于此类问题,代码框架一般如下所示: ```cpp #include <iostream> #include <vector> using namespace std; int main() { int n; cin >> n; vector<int> values(n); for (int i = 0; i < n; ++i) { cin >> values[i]; } if (n == 0) { cout << 0 << endl; return 0; } vector<int> dp(n, 0); dp[0] = values[0]; if (n >= 2) dp[1] = max(values[0], values[1]); for (int i = 2; i < n; ++i) { dp[i] = max(dp[i - 1], dp[i - 2] + values[i]); } cout << dp[n - 1] << endl; return 0; } ``` 该代码实现了基于贪心原则的动态规划求解过程,适用于某些特定场景下的最优化问题。 --- #### 可能的边界情况处理 无论使用哪种方法,都需要特别注意边界的设定与异常输入的处理。例如: - 当输入为空集合时,应返回零或提示无解; - 对于负权值的情况,需重新评估是否允许选取这些项目; - 如果存在重复计算的风险,可通过记忆化技术减少冗余操作。 以上几点均有助于提高程序鲁棒性和效率。 --- ### 结论 针对 SWUST OJ 794 的解答路径取决于实际问题描述。如果是典型的背包类问题,推荐运用动态规划;若是更倾向于局部决策累积成整体效果的情形下,则考虑引入贪心机制更为合适。最终方案还需结合具体的约束条件进一步细化调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值