洛谷——P1114 “非常男女”计划

本文介绍了一种利用相对差概念解决最长男女平衡子序列问题的算法。通过记录每个位置男女数量之差,可以高效找出最长的男女数量相等的子序列。文章详细解释了算法思路,并提供了完整的C++代码实现。

原题链接
这里我们引入相对差的概念。
很容易知道,如果第i个位置男女之差与第j个位置男女之差相等,那么第i+1到第j个位置男女人数相等。
所以,我们可以记录第i个位置的男女之差。最后遍历一遍就好了。

#include<iostream>
using namespace std;
int a[200005], l[200005], r[200005];
int max(int a, int b) {
	return a > b ? a : b;
}
int main()
{
	int n;
	cin >> n;
	int sum0 = 0, sum1 = 0;
	for (int i = 1; i <= n; i++) {
		int t;
		cin >> t;
		sum0 += (t == 0);
		sum1 += (t == 1); 
		int x = sum0 - sum1 + n;
		if (!l[x] && x != n)
			l[x] = i;
		else
			r[x] = i;
	}
	int ans = 0;
	for (int i = 0; i <= 2 * n; i++) {
		ans = max(ans, r[i] - l[i]);
	}
	cout << ans;
	return 0;
}
<think>我们需要一个简单的自定义组件,用于实现男女单选框,并且可以取消选中。 要求:使用Vue3的Composition API,组件名为GenderRadio。 功能: - 两个选项:男、女 - 初始状态未选中 - 点击选中,再次点击取消选中 - 支持v-model绑定 组件设计: - 使用props接收modelValue(用于v-model) - 使用emit发送update:modelValue事件 实现思路: 1. 创建两个选项,分别对应'male'和'female' 2. 每个选项绑定点击事件,当点击时,判断当前选项是否已被选中 如果已被选中,则取消选中(将modelValue设为null) 如果未被选中,则选中该选项(将modelValue设为该选项的值) 3. 使用computed或者ref来管理内部状态(这里直接使用props和emit即可) 注意:由于我们允许取消选中,所以需要处理点击已选中项时的逻辑。 代码结构: - 模板:使用两个div或label,显示男女,根据当前值判断是否添加选中样式 - 脚本:定义props和emit,处理点击事件 样式:简单样式,选中时改变背景色或边框色。 我们将创建一个名为GenderRadio.vue的组件。</think>### Vue3 自定义组件实现男女单选框(支持取消选中) 以下是一个简洁、可复用的自定义单选框组件实现: #### 组件文件:GenderRadio.vue ```vue <template> <div class="gender-radio"> <!-- 男性选项 --> <div class="radio-option" :class="{ selected: internalValue === 'male' }" @click="selectOption('male')" role="radio" :aria-checked="internalValue === 'male'" tabindex="0" @keydown.space="selectOption('male')" > <div class="radio-indicator"></div> <span class="label">男</span> </div> <!-- 女性选项 --> <div class="radio-option" :class="{ selected: internalValue === 'female' }" @click="selectOption('female')" role="radio" :aria-checked="internalValue === 'female'" tabindex="0" @keydown.space="selectOption('female')" > <div class="radio-indicator"></div> <span class="label">女</span> </div> </div> </template> <script setup> import { ref, computed, watch } from 'vue'; const props = defineProps({ modelValue: { type: String, default: null } }); const emit = defineEmits(['update:modelValue']); // 使用内部值以便处理取消选中逻辑 const internalValue = ref(props.modelValue); // 当外部传入的modelValue变化时更新内部值 watch(() => props.modelValue, (newVal) => { internalValue.value = newVal; }); // 选择选项的方法 const selectOption = (value) => { // 如果点击已选中的选项,则取消选中 if (internalValue.value === value) { internalValue.value = null; } else { // 否则选中新选项 internalValue.value = value; } // 触发v-model更新 emit('update:modelValue', internalValue.value); }; </script> <style scoped> .gender-radio { display: flex; gap: 16px; font-family: Arial, sans-serif; } .radio-option { display: flex; align-items: center; gap: 8px; padding: 10px 16px; border: 1px solid #dcdfe6; border-radius: 4px; cursor: pointer; transition: all 0.2s ease; background-color: #ffffff; } .radio-option:hover { border-color: #c0c4cc; background-color: #f5f7fa; } .radio-option.selected { border-color: #409eff; background-color: #ecf5ff; } .radio-indicator { width: 16px; height: 16px; border: 2px solid #c0c4cc; border-radius: 50%; position: relative; transition: all 0.2s ease; } .radio-option.selected .radio-indicator { border-color: #409eff; } .radio-option.selected .radio-indicator::after { content: ''; position: absolute; top: 2px; left: 2px; width: 8px; height: 8px; background: #409eff; border-radius: 50%; transform: scale(1); transition: transform 0.2s ease; } .label { font-size: 14px; color: #606266; } .radio-option.selected .label { color: #409eff; font-weight: 500; } /* 无障碍焦点样式 */ .radio-option:focus { outline: 2px solid #409eff; outline-offset: 2px; } </style> ``` #### 使用示例:App.vue ```vue <template> <div class="container"> <h2>选择性别</h2> <GenderRadio v-model="selectedGender" /> <div class="result" v-if="selectedGender"> 已选择: {{ selectedGender === 'male' ? '男性' : '女性' }} </div> <div class="result" v-else> 未选择性别 </div> <button @click="resetSelection" class="reset-btn">重置选择</button> </div> </template> <script setup> import { ref } from 'vue'; import GenderRadio from './components/GenderRadio.vue'; const selectedGender = ref(null); const resetSelection = () => { selectedGender.value = null; }; </script> <style> .container { max-width: 400px; margin: 40px auto; padding: 20px; border: 1px solid #ebeef5; border-radius: 8px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); font-family: Arial, sans-serif; } h2 { color: #303133; margin-bottom: 20px; } .result { margin-top: 20px; padding: 10px; background-color: #f5f7fa; border-radius: 4px; color: #606266; } .reset-btn { margin-top: 15px; padding: 8px 16px; background-color: #f56c6c; color: white; border: none; border-radius: 4px; cursor: pointer; transition: background-color 0.2s; } .reset-btn:hover { background-color: #e05d5d; } </style> ``` ### 组件特点与实现原理 1. **双向绑定支持**: - 使用 `v-model` 实现父子组件数据同步 - 通过 `modelValue` prop 接收外部值 - 使用 `emit('update:modelValue')` 更新外部值 2. **选中/取消逻辑**: ```javascript const selectOption = (value) => { if (internalValue.value === value) { internalValue.value = null; // 取消选中 } else { internalValue.value = value; // 选中 } emit('update:modelValue', internalValue.value); }; ``` 3. **响应式处理**: - 使用 `watch` 监听外部值变化,保持内部状态同步 - 使用 `ref` 创建响应式内部状态 4. **无障碍支持**: - 添加 `role="radio"` 和 `aria-checked` 属性 - 支持键盘导航(Tab 键切换,Space 键选择) - 添加焦点样式提升可访问性 5. **视觉反馈**: - 使用 CSS 过渡效果增强用户体验 - 添加悬停状态和选中状态的视觉区分 - 使用伪元素创建选中指示器 6. **组件封装**: - 自包含样式(scoped CSS) - 清晰的选项结构 - 简洁的 API 设计(仅需 v-model) ### 使用场景扩展 1. **表单集成**: ```vue <form @submit.prevent="submitForm"> <GenderRadio v-model="formData.gender" /> <button type="submit">提交</button> </form> ``` 2. **多组件组合**: ```vue <div> <h3>个人信息</h3> <GenderRadio v-model="user.gender" /> <!-- 其他表单字段 --> </div> ``` 3. **状态管理集成**: ```vue <script setup> import { useUserStore } from '@/stores/user'; const userStore = useUserStore(); </script> <template> <GenderRadio v-model="userStore.gender" /> </template> ``` ### 最佳实践建议 1. **组件复用**: - 可将组件放入 `components/form` 目录统一管理 - 添加 JSDoc 注释说明组件用法 2. **国际化支持**: - 使用 props 传递标签文本: ```vue <GenderRadio v-model="gender" male-label="男" female-label="女" /> ``` 3. **验证集成**: - 可配合 Vuelidate 或 VeeValidate 进行表单验证 4. **主题定制**: - 使用 CSS 变量支持主题切换: ```css :root { --radio-color: #409eff; } .radio-option.selected { border-color: var(--radio-color); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值