1.给定一个长度为 nn 的整数数组 a1,a2,…,an。
现在,需要你对数组中的每个元素进行分类。
每个元素要么划分至 b 类,要么划分至 c 类。
我们设所有 b 类元素的相加之和为 sumb,所有 c 类元素的相加之和为 sumc。
请你计算 sumb−sumc 的最大可能值。
如果某类元素的个数为 0,则该类元素的相加之和视为 0。
输入格式
第一行包含整数 n。
第二行包含 n 个整数 a1,a2,…,an。
输出格式
输出一个整数,表示 sumb−sumc 的最大可能值。
数据范围
前三个测试点满足 1≤n≤10。
所有测试点满足 1≤n≤100,−100≤ai≤100。
输入样例1:
3
1 -2 0
输出样例1:
3
输入样例2:
6
16 23 16 15 42 8
输出样例2:
120
思路:贪心
找一个集合最大的,另外一个最小,刚开始认为分别计数大于0,小于等于0即可;后来发现另外一个集合就是0,前面的保证正数相加(跟前面思路类似)
时间复杂度:O(n)
c++代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
int sum1,sum2;
int main()
{
cin>>n;
while(n--)
{
int x;
cin>>x;
if(x>0)sum1+=x;
else sum2+=x;
}
return cout<<sum1-sum2,0;
}
//这样做也行
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
int res = 0;
while (n -- )
{
int x;
cin >> x;
res += abs(x);
}
cout << res << endl;
return 0;
}
java代码
import java.util.*;
public class Main{
public static void main(String [] args){
Scanner cin=new Scanner(System.in);
int sum1=0,sum2=0;
int n=cin.nextInt();
while(n--!=0)
{
int x=cin.nextInt();
if(x>0)sum1+=x;
else sum2+=x;
}
System.out.println(sum1-sum2);
return ;
}
}
Python3代码
n = input()
res = list(map(int, input().split()))
print(sum(i if i > 0 else -i for i in res))
2.
有若干个单链表,每个的长度都不小于 2,任意两个链表之间不存在公共节点。
每个节点上都包含一个字符串。
不同节点上包含的字符串不同。
在这些单链表中,包含直接后继节点的节点数量为 q。
给定这 q 个节点的相关信息,请你计算并输出单链表的具体数量以及每个单链表的头节点和尾节点包含的字符串。
输入格式
第一行包含一个整数 q。
接下来 q行,每行描述一个存在直接后继节点的节点的相关信息,包含两个字符串,分别表示该节点包含的字符串以及其直接后继节点包含的字符串。
同一链表中的节点在输入中的相对顺序与在链表中的相对顺序一致。
也就是说,如果节点 a 和节点 b 都在同一链表中,且都存在直接后继节点,那么在输入节点相关信息时,a 节点的信息一定比 b 节点的信息先输入。
输出格式
第一行输出一个整数 n,表示单链表的具体数量。
接下来 n 行,每行输出两个由单个空格隔开的字符串,表示其中一个单链表的头节点和尾节点包含的字符串。
不同链表的输出顺序随意。
数据范围
前三个测试点满足 1≤q≤10。
所有测试点满足 1≤q≤1000,节点字符串由大小写字母和数字组成,长度范围 [1,20]。
思路: 模拟+哈希
时间复杂度:O(n)
c++代码
#include <iostream>
#include <cstring>
#include <algorithm>
#define x first
#define y second
using namespace std;
typedef pair<string, string> PII;
typedef long long LL;
int q;
unordered_map<string,string>mp;
vector<PII>v,ans;
int main()
{
cin>>q;
while(q--)
{
string a,b;
cin>>a>>b;
mp[a]=b;
v.push_back({a,b});
}
for (int i = 0; i < v.size(); i ++ )
{
string s=v[i].y;
if(mp.count(v[i].x))
{
while(mp.count(s))
{
string temp=s;
s=mp[s];
mp.erase(temp);
}
ans.push_back({v[i].x,s});
}
}
cout<<ans.size()<<'\n';
for(auto i:ans)
{
cout<<i.x<<' '<<i.y<<'\n';
}
//for(auto &[a,b]:ans)
// {
// cout<<a<<' '<<b<<'\n';
//}
return 0;
}
//这样做也行
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
int n;
unordered_map<string, string> head, tail;
int main()
{
cin >> n;
while (n -- )
{
string a, b;
cin >> a >> b;
if (!tail.count(a)) head[a] = b, tail[b] = a;
else head[tail[a]] = b, tail[b] = tail[a], tail.erase(a);
}
cout << head.size() << endl;
for (auto& [a, b]: head)
cout << a << ' ' << b << endl;
return 0;
}
java代码
import java.io.*;
import java.util.*;
public class Main {
public static void main(String args[]) {
Scanner cin = new Scanner(System.in);
int n=cin.nextInt();
List<String>a=new LinkedList<String>();
List<String>b=new LinkedList<String>();
for(int i=0;i<n;i++)
{
String s1=cin.next(),s2=cin.next();
if(b.contains(s1))
{
int index=b.indexOf(s1);
b.set(index,s2);
}
else
{
a.add(s1);
b.add(s2);
}
}
int len=a.size();
System.out.println(len);
for(int i=0;i<len;i++)
System.out.println(a.get(i)+" "+b.get(i));
}
}
Python3代码
def main():
n = int(input())
b_a = dict()
for _ in range(n):
x, y = input().split()
if x in b_a:
a = b_a[x]
del b_a[x]
b_a[y] = a
else:
b_a[y] = x
rn = len(b_a)
print(rn)
for b, a in b_a.items():
print("{} {}".format(a, b))
if __name__ == "__main__":
main()
3.
给定 n 个由小写字母构成的字符串。
现在,请你对它们进行归类。
对于两个字符串 a 和 b:
- 如果至少存在一个字母在 a 和 b 中同时出现,则 a 和 b 属于同一类字符串。
- 如果字符串 c 既与字符串 a 同类,又与字符串 b 同类,则 a 和 b 属于同一类字符串。
请问,最终所有字符串被划分为多少类。
输入格式
第一行包含整数 n。
接下来 n 行,每行包含一个仅由小写字母构成的字符串。
注意,输入字符串可能相同。
输出格式
一个整数,表示最终所有字符串被划分为的类的数量。
数据范围
前 6 个测试点满足 1≤n≤10。
所有测试点满足 1≤n≤2×10^5,输入字符串的长度范围 [1,50],所有输入字符串的总长度范围 [1,106],所有字符串均由小写英文字母构成。
思路:并查集(合并字母)
看下有几个字母集合即可
c++代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 30;
int n;
int p[N];
bool st[N];
int find(int x)
{
return p[x]==x?p[x]:p[x]=find(p[x]);
}
int main()
{
cin>>n;
for (int i = 0; i < 26; i ++ )p[i]=i;
while (n -- )
{
string s;
cin>>s;
int x=find(s[0]-'a');
st[s[0]-'a']=true;
for(int i=1;i<s.size();i++)
{
st[s[i]-'a']=true;
int y=find(s[i]-'a');
if(x!=y)p[y]=x;
}
}
int res=0;
for (int i = 0; i < 26; i ++ )
if(st[i]&&p[i]==i)res++;
return cout<<res,0;
}
//这样做也行
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200010;
int n;
int p[N];
int id[26];
char str[55];
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) p[i] = i;
int res = n;
for (int i = 1; i <= n; i ++ )
{
scanf("%s", str);
for (int j = 0; str[j]; j ++ )
{
int c = str[j] - 'a';
if (id[c])
{
if (find(i) != find(id[c]))
{
p[find(i)] = find(id[c]);
res -- ;
}
}
else id[c] = i;
}
}
printf("%d\n", res);
return 0;
}
java代码
import java.io.*;
import java.util.*;
public class Main {
static int p[]=new int[26];
static int ss[]=new int[26];
public static int find(int x){
if(p[x]!=x){
p[x]=find(p[x]);
}
return p[x];
}
public static void main(String args[]) {
Scanner cin = new Scanner(System.in);
int n=cin.nextInt();
for(int i=0;i<26;i++)p[i]=i;
for (int i=0;i<n;i++)
{
String s=cin.next();
int x=s.charAt(0)-'a';
for (char c:s.toCharArray())
{
int id=c-'a';
if(find(id)!=find(x))
p[find(id)]=find(x);
ss[id]=1;
}
}
int ans=0;
for(int i=0;i<26;i++)
if(ss[i]>0&&p[i]==i)ans++;
System.out.println(ans);
return;
}
}
欢迎留言点赞
嗷嗷嗷