CF Round 423 Div2 PC(思维题)

探讨了在给定字符串及其位置约束下寻找字典序最小字符串的问题,介绍了三种优化方法:改进赋值过程减少重复操作、利用字符串动态内存节省空间及采用并查集提高效率。

题意就是给你n个串,和这些串出现的位置,要你求满足这些条件的字典序最小的串,串的长度不超过1e6

开始想着暴力+线段树优化结果给t了,问题就在于,我优化的时候,如果这个区间就算有一个值没被优化掉那么就整个串都要被赋值一遍,并没有优化的特别好

然后看到一种让人吐血的优化方法,就是对于每个串,因为位置是严格递增的,那么我就记录上一个串的结束位置,然后从这里开始再进行赋值,(其实并没有优化多少但是过了0.0)

代码如下

 #include <iostream>  
    #include <cstdio>  
    #include <cstring>  
    #include <string>  
    #include <algorithm>  
    #include <cmath>  
    #include <map>  
    #include <set>  
    #include <stack>  
    #include <queue>  
    #include <vector>  
    #include <bitset>  
      
    using namespace std;  
      
    #define LL long long  
    const int INF = 0x3f3f3f3f;  
    #define MAXN 500  
      
    char s[2000006];  
    char ch[2000005];  
    int main()  
    {  
        int n,m,x;  
      
        int tot=0;  
        scanf("%d",&n);  
        for(int i=0; i<n; i++)  
        {  
            scanf("%s%d",&ch,&m);  
            int k=strlen(ch);  
            int t=-INF;  
            for(int j=0; j<m; j++)  
            {  
                scanf("%d",&x);  
                x--;  
                tot=max(x+k,tot);  
                for(int l=max(x,t); l<x+k; l++)  
                    s[l]=ch[l-x];  
                t=x+k;  
            }  
        }  
        for(int i=0; i<tot; i++)  
            if(s[i]=='\0')  
                printf("a");  
            else  
                printf("%c",s[i]);  
        printf("\n");  
      
        return 0;  
    }  
然后看到了另外一种优化

就是我先把所有的输入数据读进来

这里就必须要用String,因为string是动态内存嘛,可以节省空间复杂度的

然后我们记录每个串的长度和起始位置


之后我们按照起始位置从小到大排序

然后也是向前面一个一样,从上一个的末尾开始进行赋值,这样时间复杂度就要小很多了,但是有点虚的,毕竟空间复杂度爆表了都

要是数据厉害点也过不了

    #include <cstdio>  
    #include <string>  
    #include <iostream>  
    #include <queue>  
    #include <cstring>  
    #include <algorithm>  
    using namespace std;  
    #define mst(a,b) memset((a),(b),sizeof(a))  
    #define rush() int T;scanf("%d",&T);while(T--)  
      
    typedef long long ll;  
    const int maxn= 1000005;  
    const int mod = 1e9+7;  
    const int INF = 0x3f3f3f3f;  
    const double eps = 1e-6;  
      
    struct node  
    {  
        int pos,id;  
    }a[maxn];  
      
    bool cmp(const node &a,const node &b)  
    {  
        return a.pos<b.pos;  
    }  
      
    string  s[maxn];  
      
    int main()  
    {  
        int n,k,x;  
        int cnt=0;  
        scanf("%d",&n);  
        for(int i=0;i<n;i++)  
        {  
            cin>>s[i];  
            scanf("%d",&k);  
            for(int j=0;j<k;j++)  
            {  
                scanf("%d",&x);  
                a[cnt].pos=x;  
                a[cnt++].id=i;  
            }  
        }  
        sort(a,a+cnt,cmp);  
        string ans;  
        int now=1;  
        for(int i=0;i<cnt;i++)  
        {  
            while(now<a[i].pos)  
            {  
                ans+='a';  
                now++;  
            }  
            for(int j=now-a[i].pos;j<s[a[i].id].length();j++)  //这里的起点是优化之处  
            {  
                ans+=s[a[i].id][j];  
                now++;  
            }  
        }  
        cout<<ans<<endl;  
    }  

还有一种方法就是运用并查集

开始想的是对每个连续的序列做一个集合,并记录他的l和r

这个思路应该是对的但是还是莫名其妙给wa了

然后看到另一种思路是,用并查集find_r(x)找到的是x之后最近的没有赋值的位置,这样就好些多了

还是不够有灵性啊


<route lang="yaml"> meta: enabled: false </route> <script setup lang="ts"> // import { VxeUI, VxeToolbarPropTypes, VxeToolbarEvents } from 'vxe-table' import type { VxePagerEvents,VxeGridListeners, VxeGridProps,VxeColumnPropTypes,VxeToolbarPropTypes, VxeToolbarEvents,VxeToolbarInstance,VxeTableInstance,VxeTablePropTypes} from 'vxe-table' import apiTransaction from '@/api/modules/transaction' import { timeShortcuts } from '@/utils/timeShortcuts' import VxeUI from 'vxe-pc-ui' import useUserStore from '@/store/modules/user' import defaultAvatar from '@/assets/images/default-avatar.png' import useSettingsStore from '@/store/modules/settings' import VxeUITable from 'vxe-table' import type { VxeFormProps, VxeFormListeners } from 'vxe-pc-ui' defineOptions({ name: 'TransactionList', }) const userStore = useUserStore() const tableData = shallowRef<RowVO[]>([]) const transactionTypeOptions = [ { value: '', label: '全部' }, { value: 0, label: '支付' }, { value: 1, label: '充值' }, { value: 2, label: '退款' }, { value: 3, label: '补缴' }, ] const statusOptions = [ { value: '', label: '全部' }, { value: 0, label: '待处理' }, { value: 1, label: '处理中' }, { value: 2, label: '成功' }, { value: 3, label: '失败' }, { value: 4, label: '已过期' }, { value: 5, label: '已关闭' } ]; // 退款类型 const refundTypesMap :Record<number, { name: string; color: string }> = { 1: { name: '本金退款', color: '#3B82F6' }, // 橙色 2: { name: '赠金扣款', color: '#2A9D8F' }, // 青绿色 } // 退款方式 const refundModeMap :Record<number, { name: string; color: string }> = { 1: { name: '原路退回', color: '#3B82F6' }, // 橙色 2: { name: '人工处理', color: '#2A9D8F' }, // 青绿色 } // 交易类型映射 const transactionTypeMap: Record<number, { name: string; color: string }> = { 0: { name: '支付', color: '#3B82F6' }, // 蓝色 - 充电订单支付 1: { name: '充值', color: '#10B981' }, // 绿色 - 用户/系统充值 2: { name: '退款', color: '#F59E0B' }, // 橙色 - 充电订单退款 3: { name: '补缴', color: '#EF4444' } // 红色 - 充电订单补缴 }; // 交易状态映射 const statusMap: Record<number, { name: string; color: string }> = { 0: { name: '待处理', color: '#9CA3AF' }, // 灰色 - 交易已创建 1: { name: '处理中', color: '#F59E0B' }, // 橙色 - 交易进行中 2: { name: '成功', color: '#10B981' }, // 绿色 - 交易成功 3: { name: '失败', color: '#EF4444' }, // 红色 - 交易失败 4: { name: '已过期', color: '#6B7280' }, // 深灰 - 交易超时 5: { name: '已关闭', color: '#6B7280' } // 深灰 - 交易关闭 }; // 支付方式映射 // const payModeMap: Record<number, { name: string; color: string }> = { // 0: { name: '未知支付', color: '#9CA3AF' }, // 灰色 // 1: { name: '在线支付', color: '#3B82F6' }, // 蓝色 // 2: { name: '集团支付', color: '#8B5CF6' }, // 紫色 // 3: { name: '鉴权卡', color: '#EC4899' }, // 粉色 // 4: { name: '用户余额', color: '#10B981' }, // 绿色 // 5: { name: '钱包卡', color: '#F59E0B' }, // 橙色 // 6: { name: '后台', color: '#6366F1' }, // 靛蓝 // 7: { name: 'VIN', color: '#14B8A6' }, // 蓝绿色 // 1000: { name: '第三方平台', color: '#F97316' } // 深橙色 // }; // 支付渠道映射 const payChannelMap: Record<number, { name: string; color: string }> = { 0: { name: '未知渠道', color: '#9CA3AF' }, // 灰色 1: { name: '余额', color: '#10B981' }, // 绿色 2: { name: '微信', color: '#22C55E' } // 亮绿色(微信品牌色) }; const settingsStore = useSettingsStore() watch(() => settingsStore.currentColorScheme, () => { VxeUITable.setTheme(settingsStore.currentColorScheme!) }, { immediate: true, }) // 类型定义 interface RowVO { id: number; //id customer_id: string; // 客户ID avatar: string; // 头像 customer_name: string; // 客户 account_name: string; // 账户名称 operator_id: string; // 运营商ID operator_name: string; // 运营商名称 type: number; // 交易类型 pay_channel: number; // 支付渠道 pay_mode: number; // 支付方式 status: number; // 交易状态 platform_id: string; // 平台ID platform_name: string; // 平台名称 out_order_id: string; // 订单号 out_refund_order_id: string; // 退款订单号 platform_transaction_id: string; // 平台单号 amount: number; // 退款金额 principal_amount: number; gift_amount: number; // 赠金 before_balance: number; // 交易前余额 after_balance: number; // 交易后余额 refund_type: number; // 退款类型(1: 原路退回, 2: 人工退款) refund_mode: number; // 退款方式(1: 本金退款, 2: 赠金扣款) remark: string; // 备注 finish_time: string; // 完成时间 created_at: string;// 创建时间 loading?: boolean; } const data = ref({ loading:true, keyword:'', pagerConfig:{ total: 0, currentPage: 1, pageSize: 10 }, }) // 刷新流水 async function onRefresh(row: RowVO) { try { row.loading = true; await apiTransaction.refreshTransaction({ id: row.id.toString(), }); } catch (error) { console.error('刷新交易失败:', error); } finally { setTimeout(() => { row.loading = false }, 3000) } } // 加载表格数据 function getData() { data.value.loading = false const formData = formOptions.data const params = { page: data.value.pagerConfig.currentPage, pageSize: data.value.pagerConfig.pageSize, ...(formData?.type && { type: Number(formData.type) }), ...(formData?.status && { status: Number(formData.status) }), ...(formData?.phone?.trim() && { phone: formData.phone.trim() }), ...(formData?.id?.trim() && { id: formData.id.trim() }), ...(formData?.operator_id?.trim() && { operator_id: formData.operator_id.trim() }), ...(formData?.platform_id?.trim() && { platform_id: formData.platform_id.trim() }), ...(data.value.keyword && { keyword: data.value.keyword }), ...(formData?.created_at && { start_time: formData?.created_at[0], end_time: formData?.created_at[1], }), }; apiTransaction.transactionList(params).then((res) => { // 使用新数组替换,触发shallowRef更新 tableData.value = [...res.data.list]; data.value.pagerConfig.total = res.data.total; // data.tableData = tableData.value; }).catch((error) => { console.error('加载数据失败:', error) }).finally(() => { data.value.loading = false }) } // 初始化加载 onMounted(() => { for (let i = 0; i < 10; i++) { tableData.value.push({ id: 10002122121213111 + i, customer_id: '10002122121213111', avatar: 'https://p3-flow-imagex-sign.byteimg.com/ocean-cloud-tos/image_skill/55e1ac2e-7b0d-439c-a368-ae574eccb5b6_1749951146378770644~tplv-a9rns2rl98-web-thumb-watermark-v2.jpeg?rk3s=b14c611d&x-expires=1781487146&x-signature=rnQnWXNqI0XnI5ODJyBfNqTV0rM%3D', customer_name: '客户' + (i + 1), account_name: '账户' + (i + 1), operator_id: 'OP100013213232342' + (i % 3 + 1), operator_name: ['移动', '联通', '电信'][i % 3], type: [1, 2, 3][i % 3], // 假设1:充值 2:消费 3:退款 pay_channel: [1, 2, 3][i % 3], // 假设1:支付宝 2:微信 3:银联 pay_mode: [1, 2][i % 2], // 假设1:在线 2:线下 status: [0, 1, 2, 3][i % 4], // 0-3状态 platform_id: 'PL' + (100 + i), platform_name: ['支付宝', '微信支付', '银联'][i % 3], out_order_id: 'ORD' + Date.now().toString().slice(-12) + i, out_refund_order_id: 'REF' + Date.now().toString().slice(-12) + i, platform_transaction_id: 'TRX' + Date.now().toString().slice(-18) + i, amount: 100.50 + i * 10, principal_amount: 95.00 + i * 10, gift_amount: 5.50 + i, before_balance: 500.00 + i * 50, after_balance: 400.00 + i * 50, refund_type: [1, 2][i % 2], // 1:原路退回 2:人工退款 refund_mode: [1, 2][i % 2], // 1:本金退款 2:赠金扣款 remark: `测试交易数据${i + 1}` + (i % 3 === 0 ? '(加急处理)' : ''), finish_time:'2023-05-15 14:30:' + (22 + i).toString().padStart(2, '0'), created_at: '2023-05-15 14:30:' + (22 + i).toString().padStart(2, '0') }); } // data.tableData=tableData.value // getData() const $table = tableRef.value const $toolbar = toolbarRef.value if ($table && $toolbar) { $table.connect($toolbar) } }) // 清理工作 onUnmounted(() => { tableData.value = [] }) function formatLocal(date: Date): string { return new Intl.DateTimeFormat('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).format(date) .replace(/\//g, '-') .replace(/(\d{2}):(\d{2}):(\d{2})/, '$1:$2:$3'); } // 个性化列 const toolbarRef = ref<VxeToolbarInstance>() const tableRef = ref<VxeTableInstance>() // 实时更新 const customConfig = reactive<VxeTablePropTypes.CustomConfig>({ immediate: true, }) // 搜索表单 interface FormDataVO { id: string type: string | number operator_id: string platform_id: string phone: string status: string | number created_at: [string, string] // 新增时间范围字段 } // 搜索配置 const formOptions = reactive<VxeFormProps<FormDataVO>>({ data: { id: '', type: '', operator_id: '', // 运营商 id platform_id: '', // 平台 id phone: '', status: '', created_at: [ formatLocal(new Date(new Date().setHours(0, 0, 0, 0))), // 当天开始时间 00:00:00 formatLocal(new Date(new Date().setHours(23, 59, 59, 0))), // 当天结束时间 23:59:59 ], // 新增时间范围 }, size:'small', items: [ { field: 'id', title: '单号', span: 4, folding: true,itemRender: { name: 'VxeInput' } }, { field: 'operator_id', title: '运营商ID', span: 4,folding: true, itemRender: { name: 'VxeInput' } }, { field: 'platform_id', title: '平台ID', span: 4,folding: true, itemRender: { name: 'VxeInput' } }, { field: 'phone', title: '手机号', span: 4, folding: true, itemRender: { name: 'VxeInput' } }, { field: 'type', title: '交易类型', span: 4, folding: false, itemRender: { name: 'VxeSelect', options: transactionTypeOptions, }, }, { field: 'status', title: '交易状态', span: 4, folding: false, itemRender: { name: 'VxeSelect', options: statusOptions, }, }, { field: 'created_at', // 新增时间筛选字段 title: '交易时间', span: 8, folding: false, slots: { default: 'default_created_at' }, // 使用插槽渲染 }, { span: 5, collapseNode: true, align: 'center', itemRender: { name: 'VxeButtonGroup', options: [ { type: 'submit',size:'small', content: '搜索',icon: 'i-ep:search', status: 'primary' }, // { type: 'reset', content: '重置' } ] } } ] }) // 表单搜索按钮操作 const formEvents: VxeFormListeners = { submit () { getData() }, reset () { getData() } } // 左侧按钮 const toolbarButtons = ref<VxeToolbarPropTypes.Buttons>([ { name: '刷新', code: 'refresh', status: 'info', icon: 'i-ep:refresh' }, ]) // 左侧按钮事件 const buttonClickEvent: VxeToolbarEvents.ButtonClick = ({ code }) => { if (code ==='refresh') { getData() } } // 分页查询事件 const onPageChange: VxePagerEvents.PageChange = ({ pageSize, currentPage }) => { data.value.pagerConfig.currentPage = currentPage data.value.pagerConfig.pageSize = pageSize getData() } </script> <template> <div> <FaPageMain> <vxe-form v-bind="formOptions" v-on="formEvents"> <template #default_created_at="{ data }"> <el-date-picker v-model="data.created_at" style="width: 100%;" type="datetimerange" start-placeholder="开始时间" end-placeholder="结束时间" range-separator="至" :shortcuts="timeShortcuts" :default-time="[ new Date(2000, 1, 1, 0, 0, 0), // 开始时间默认 00:00:00 new Date(2000, 1, 1, 23, 59, 59), // 结束时间默认 23:59:59 ]" /> </template> </vxe-form> <vxe-toolbar :buttons="toolbarButtons" @button-click="buttonClickEvent" ref="toolbarRef" size="mini" custom> <template #tools> <vxe-input v-model="data.keyword" type="search" clearable placeholder="单号/订单号/退款订单号/平台单号" style="width: 180px;margin-right: 10px;" @keyup.enter="data.pagerConfig.currentPage=1,getData()" @clear="data.pagerConfig.currentPage=1,getData()" /> </template> </vxe-toolbar> <vxe-table id="table_toolbar_custom" ref="tableRef" size="small" round stripe :loading="data.loading" :custom-config="customConfig" :column-config="{useKey: true}" :row-config="{useKey: true}" :data="tableData"> <vxe-column field="id" title="单号" width="185" align="center"></vxe-column> <vxe-column field="customer_id" title="客户ID" width="185" align="center"> <template #default="{ row }"> <vxe-button mode="text" status="primary" @click="onRefresh(row)">{{ row.customer_id }}</vxe-button> </template> </vxe-column> <vxe-column field="avatar" title="头像" :visible="false" width="185" align="center"> <template #default="{ row }"> <vxe-button mode="text" status="primary" @click="onRefresh(row)">刷新</vxe-button> </template> </vxe-column> <vxe-column field="customer_name" title="账户名称" width="185" align="center"></vxe-column> <vxe-column field="operator_name" title="运营商" width="185" align="center"> <template #default="{ row }"> <vxe-button mode="text" status="primary" @click="onRefresh(row)">{{row.operator_name}}</vxe-button> </template> </vxe-column> <vxe-column field="type" title="交易类型" :visible="false" width="185" align="center"></vxe-column> <vxe-column field="pay_channel" title="支付渠道" width="185" :visible="false" align="center"></vxe-column> <vxe-column field="platform" title="支付平台" width="185" :visible="false" align="center"></vxe-column> <vxe-column field="out_order_id" title="订单号" :visible="false" width="185" align="center"></vxe-column> <vxe-column field="out_refund_order_id" title="退款订单号" :visible="false" width="185" align="center"></vxe-column> <vxe-column field="refund_info" title="退款信息" width="185" :visible="false" align="center"></vxe-column> <vxe-column field="platform_transaction_id" title="平台支付单号" :visible="false" width="185" align="center"></vxe-column> <vxe-column field="amount" title="交易金额" width="185" align="center"></vxe-column> <vxe-column field="pay_amount" title="金额来源" width="185" align="center"></vxe-column> <vxe-column field="before_balance" title="交易前后余额" :visible="false" width="185" align="center"></vxe-column> <vxe-column field="status" title="状态" width="185" align="center" type="html" :formatter="({cellValue}) => { return `<span style='color: ${statusMap[cellValue].color}'>${statusMap[cellValue].name}</span>` }" ></vxe-column> <vxe-column field="remark" title="备注" :visible="false" width="180"> <template #default="{ row }"> <vxe-text-ellipsis line-clamp="2" :content="row.remark"></vxe-text-ellipsis> </template> </vxe-column> <vxe-column field="time" title="交易时间" width="200" :formatter="({row}) => { return `创建:${row.created_at || '--'}\n完成:${row.finish_time || '--'}`; }"></vxe-column> <vxe-column title="操作" width="90" fixed="right" align="center"> <template #default="{ row }"> <vxe-button mode="text" status="primary" :loading="row.loading" @click="onRefresh(row)">刷新</vxe-button> </template> </vxe-column> <!-- <vxe-column field="操作" title="操作" width="185" fixed="right" align="center"></vxe-column> --> </vxe-table> <!-- 分页 --> <vxe-pager v-model:currentPage="data.pagerConfig.currentPage" v-model:pageSize="data.pagerConfig.pageSize" :total="100" :pageSizes="[10,20]" @page-change="onPageChange"> </vxe-pager> </FaPageMain> </div> </template> <style scoped> .loading-placeholder { min-height: 200px; padding: 16px; background-color: var(--el-bg-color); border-radius: 4px; } :deep(.transition-height) { /* 设置面板外边距 */ padding: 10px 20px !important; } /* 调整表格中搜索内容form和表格的间距 */ :deep(.vxe-grid--layout-header-wrapper) { margin-bottom: 10px; } </style> 设置骨架屏
最新发布
06-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值