4 solutions
-
0
N = int(input()) K = int(input()) data = list(map(int,input().split())) st = set() mp = {} for i in range(0,N,K): data_num =data[i:i+K] data_set =tuple(data_num) data_str = ''.join(map(str,data_num)) if data_str in st: mp[data_set]+=1 else: st.add(data_str) mp[data_set]=1 res = [] for data_set,ant in mp.items(): for number in data_set: res.append(int(number)) res.append(ant) print(*res)
-
0
题面描述:
数据重删是一种用于节约存储空间的技术,旨在识别和处理存储池内的重复数据块。其基本思路是,在多个重复的数据块中仅保留一份,通过地址指针指向这份唯一的数据。给定一组数据及其块的大小,需要设计一个方法判断当前数据块是否与之前的数据库重复。如果发现重复,需将该数据库删除,并在首次出现的数据库后增加重复计数,最终输出处理后的数据内容,格式为以空格分隔的数字,且最后没有空格。输入包括一个整数 (数据个数)、一个整数 (数据块大小)及 个整数(数据值),输出则为去除重复数据后的结果,例如对于输入
8 2 1 2 3 4 1 2 3 4
,输出为1 2 2 3 4 2
。题目思路
该题的要点是要统计出要多少个数据块,所以先将数组按照大小为k进行分段,并且对每一段进行计数,将相同的数据块一次输出。可以考虑使用map来对数据块计数。计数完毕后,再重新分段遍历数组,当map中存在该数据段时,一次性将其输出,并且将该数据段从map中删除,防止重复输出。
解题步骤
-
数据输入与初始化:
- 读取输入数据的个数 和数据块的大小 。
- 将输入的 个整数存储在一个数组中。
-
数据分块:
- 使用一个循环将数据按大小为 进行分割,生成一个字符串形式的子数组。
- 使用
stringstream
将每个子数组的元素连接为字符串,并存入一个vector<string>
中。
-
统计出现频次:
- 使用
unordered_map
来记录每个子数组字符串的出现次数。 - 另一个
unordered_map
用于存储子数组首次出现的索引,以便后续排序。
- 使用
-
构建结果集合:
- 遍历统计结果,将子数组、频次和索引封装成三元组,并存储在一个向量中。
- 根据首次出现的索引对三元组向量进行排序,确保输出顺序与输入一致。
-
格式化输出:
- 将处理后的结果拼接为最终输出字符串,确保格式正确,且没有多余的空格。
代码
python
n = int(input()) # 读取数组 a 的长度 k = int(input()) # 读取分割 a 的块大小 a = list(map(int, input().split())) # 读取数组 a parts = [] # 存储分割后的子数组 # 将数组 a 分成 k 份 left = 0 while left < n: right = min(left + k - 1, n - 1) # 确定当前子数组的右边界 parts.append(" ".join(map(str, a[left:right + 1]))) # 将当前子数组转为字符串并添加到 parts 列表中 left = right + 1 # 更新左边界,准备处理下一个子数组 mp = {} # 用于存储子数组出现的频次 idx = {} # 用于存储子数组第一次出现的索引 for i in range(len(parts)): if parts[i] not in mp: # 如果子数组第一次出现 mp[parts[i]] = 1 # 将其频次设为 1 idx[parts[i]] = i # 记录其首次出现的索引 else: mp[parts[i]] += 1 # 否则增加其频次 res = [] # 用于存储 (子数组, 频次, 索引) 的三元组 for key in mp: res.append((key, mp[key], idx[key])) # 构建三元组并添加到 res 列表中 res.sort(key=lambda x: (x[2])) # 根据索引对 res 列表进行排序 output = "" # 初始化输出字符串 for x in res: output += x[0] + " " + str(x[1]) + " " # 将每个三元组的内容拼接到输出字符串中 output = output[:-1] # 去掉最后多余的空格 print(output) # 输出结果
java
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int k = sc.nextInt(); List<String> parts = new ArrayList<>(); int left = 0; // 把数组切成长k份 while (left < n) { int right = Math.min(left + k - 1, n - 1); StringBuilder sb = new StringBuilder(); for (int i = left; i <= right; i++) { if (i > left) { sb.append(" "); } sb.append(sc.nextInt()); } parts.add(sb.toString()); left = right + 1; } // 计算每个部分的出现次数 以及 第一次出现的位置 Map<String, Integer> mp = new HashMap<>(); Map<String, Integer> idx = new HashMap<>(); for (int i = 0; i < parts.size(); i++) { String part = parts.get(i); if (!mp.containsKey(part)) { mp.put(part, 1); idx.put(part, i); } else { mp.put(part, mp.get(part) + 1); } } // 按照第一次出现的位置排序 List<List<Object>> res = new ArrayList<>(); for (Map.Entry<String, Integer> entry : mp.entrySet()) { List<Object> tuple = new ArrayList<>(); tuple.add(entry.getKey()); tuple.add(entry.getValue()); tuple.add(idx.get(entry.getKey())); res.add(tuple); } res.sort(Comparator.comparingInt(list -> (int) list.get(2))); // 输出结果 StringBuilder output = new StringBuilder(); for (List<Object> tuple : res) { output.append(tuple.get(0)).append(" ").append(tuple.get(1)).append(" "); } System.out.println(output.toString().trim()); } }
C++
#include <iostream> #include <vector> #include <unordered_map> #include <algorithm> #include <sstream> using namespace std; // 将字符串按给定的分隔符分割成字符串向量 vector<string> split(const string& str, char delimiter) { vector<string> result; stringstream ss(str); string token; while (getline(ss, token, delimiter)) { result.push_back(token); } return result; } int main() { int n, k; cin >> n >> k; // 读取数组 a 的长度 n 和分割大小 k vector<int> a(n); for (int i = 0; i < n; i++) { cin >> a[i]; // 读取数组 a 的元素 } vector<string> parts; // 存储分割后的子数组 int left = 0; while (left < n) { int right = min(left + k - 1, n - 1); // 确定当前子数组的右边界 stringstream ss; for (int i = left; i <= right; i++) { if (i > left) { ss << " "; // 在子数组元素之间添加空格 } ss << a[i]; // 将当前元素添加到子数组字符串中 } parts.push_back(ss.str()); // 将当前子数组字符串添加到 parts 向量中 left = right + 1; // 更新左边界,准备处理下一个子数组 } unordered_map<string, int> mp; // 用于存储子数组出现的频次 unordered_map<string, int> idx; // 用于存储子数组第一次出现的索引 for (int i = 0; i < parts.size(); i++) { if (mp.count(parts[i]) == 0) { // 如果子数组第一次出现 mp[parts[i]] = 1; // 将其频次设为 1 idx[parts[i]] = i; // 记录其首次出现的索引 } else { mp[parts[i]]++; // 否则增加其频次 } } // 构建 (子数组, 频次, 索引) 的三元组向量 vector<tuple<string, int, int>> res; for (const auto& [key, value] : mp) { res.emplace_back(key, value, idx[key]); } // 根据索引对三元组向量进行排序 sort(res.begin(), res.end(), [](const auto& a, const auto& b) { return get<2>(a) < get<2>(b); }); string output; // 初始化输出字符串 for (const auto& t : res) { string part = get<0>(t); int count = get<1>(t); int _ = get<2>(t); // 或者忽略这个变量如果不需要 output += part + " " + to_string(count) + " "; // 将每个三元组的内容拼接到输出字符串中 } output.pop_back(); // 去掉最后多余的空格 cout << output << endl; // 输出结果 return 0; }
-
-
0
我直接用map存储vector和值_(:3JZ)_
#include<bits/stdc++.h> using namespace std; map<vector<int>,int>mp; int main(){ int N,K; cin>>N>>K; int k=0; vector<int>a; vector<int>b[N/K+10]; int cnt=0; for(int i=1;i<=N;i++){ int x;cin>>x; a.push_back(x); k++; if(k==K){ k=0; if(mp.find(a)!=mp.end())mp[a]++; else { mp[a]=1; b[++cnt]=a; } a.clear(); } } if(N%K){ mp[a]++; b[++cnt]=a; } for(int i=1;i<=cnt;i++){ for(auto&x:b[i])cout<<x<<" "; cout<<mp[b[i]]<<" "; } return 0; }
-
0
题目思路
该题的要点是要统计出要多少个数据块,所以先将数组按照大小为k进行分段,并且对每一段进行计数,将相同的数据块一次输出。可以考虑使用map来对数据块计数。计数完毕后,再重新分段遍历数组,当map中存在该数据段时,一次性将其输出,并且将该数据段从map中删除,防止重复输出。
代码
python
n = int(input()) # 读取数组 a 的长度 k = int(input()) # 读取分割 a 的块大小 a = list(map(int, input().split())) # 读取数组 a parts = [] # 存储分割后的子数组 # 将数组 a 分成 k 份 left = 0 while left < n: right = min(left + k - 1, n - 1) # 确定当前子数组的右边界 parts.append(" ".join(map(str, a[left:right + 1]))) # 将当前子数组转为字符串并添加到 parts 列表中 left = right + 1 # 更新左边界,准备处理下一个子数组 mp = {} # 用于存储子数组出现的频次 idx = {} # 用于存储子数组第一次出现的索引 for i in range(len(parts)): if parts[i] not in mp: # 如果子数组第一次出现 mp[parts[i]] = 1 # 将其频次设为 1 idx[parts[i]] = i # 记录其首次出现的索引 else: mp[parts[i]] += 1 # 否则增加其频次 res = [] # 用于存储 (子数组, 频次, 索引) 的三元组 for key in mp: res.append((key, mp[key], idx[key])) # 构建三元组并添加到 res 列表中 res.sort(key=lambda x: (x[2])) # 根据索引对 res 列表进行排序 output = "" # 初始化输出字符串 for x in res: output += x[0] + " " + str(x[1]) + " " # 将每个三元组的内容拼接到输出字符串中 output = output[:-1] # 去掉最后多余的空格 print(output) # 输出结果
java
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int k = sc.nextInt(); List<String> parts = new ArrayList<>(); int left = 0; // 把数组切成长k份 while (left < n) { int right = Math.min(left + k - 1, n - 1); StringBuilder sb = new StringBuilder(); for (int i = left; i <= right; i++) { if (i > left) { sb.append(" "); } sb.append(sc.nextInt()); } parts.add(sb.toString()); left = right + 1; } // 计算每个部分的出现次数 以及 第一次出现的位置 Map<String, Integer> mp = new HashMap<>(); Map<String, Integer> idx = new HashMap<>(); for (int i = 0; i < parts.size(); i++) { String part = parts.get(i); if (!mp.containsKey(part)) { mp.put(part, 1); idx.put(part, i); } else { mp.put(part, mp.get(part) + 1); } } // 按照第一次出现的位置排序 List<List<Object>> res = new ArrayList<>(); for (Map.Entry<String, Integer> entry : mp.entrySet()) { List<Object> tuple = new ArrayList<>(); tuple.add(entry.getKey()); tuple.add(entry.getValue()); tuple.add(idx.get(entry.getKey())); res.add(tuple); } res.sort(Comparator.comparingInt(list -> (int) list.get(2))); // 输出结果 StringBuilder output = new StringBuilder(); for (List<Object> tuple : res) { output.append(tuple.get(0)).append(" ").append(tuple.get(1)).append(" "); } System.out.println(output.toString().trim()); } }
C++
#include <iostream> #include <vector> #include <unordered_map> #include <algorithm> #include <sstream> using namespace std; // 将字符串按给定的分隔符分割成字符串向量 vector<string> split(const string& str, char delimiter) { vector<string> result; stringstream ss(str); string token; while (getline(ss, token, delimiter)) { result.push_back(token); } return result; } int main() { int n, k; cin >> n >> k; // 读取数组 a 的长度 n 和分割大小 k vector<int> a(n); for (int i = 0; i < n; i++) { cin >> a[i]; // 读取数组 a 的元素 } vector<string> parts; // 存储分割后的子数组 int left = 0; while (left < n) { int right = min(left + k - 1, n - 1); // 确定当前子数组的右边界 stringstream ss; for (int i = left; i <= right; i++) { if (i > left) { ss << " "; // 在子数组元素之间添加空格 } ss << a[i]; // 将当前元素添加到子数组字符串中 } parts.push_back(ss.str()); // 将当前子数组字符串添加到 parts 向量中 left = right + 1; // 更新左边界,准备处理下一个子数组 } unordered_map<string, int> mp; // 用于存储子数组出现的频次 unordered_map<string, int> idx; // 用于存储子数组第一次出现的索引 for (int i = 0; i < parts.size(); i++) { if (mp.count(parts[i]) == 0) { // 如果子数组第一次出现 mp[parts[i]] = 1; // 将其频次设为 1 idx[parts[i]] = i; // 记录其首次出现的索引 } else { mp[parts[i]]++; // 否则增加其频次 } } // 构建 (子数组, 频次, 索引) 的三元组向量 vector<tuple<string, int, int>> res; for (const auto& [key, value] : mp) { res.emplace_back(key, value, idx[key]); } // 根据索引对三元组向量进行排序 sort(res.begin(), res.end(), [](const auto& a, const auto& b) { return get<2>(a) < get<2>(b); }); string output; // 初始化输出字符串 for (const auto& t : res) { string part = get<0>(t); int count = get<1>(t); int _ = get<2>(t); // 或者忽略这个变量如果不需要 output += part + " " + to_string(count) + " "; // 将每个三元组的内容拼接到输出字符串中 } output.pop_back(); // 去掉最后多余的空格 cout << output << endl; // 输出结果 return 0; }
- 1
Information
- ID
- 101
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 5
- Tags
- # Submissions
- 715
- Accepted
- 213
- Uploaded By