C++笔试强训day12

目录

1.删除公共字符

2.两个链表的第一个公共结点

3.mari和shiny


1.删除公共字符

链接icon-default.png?t=N7T8https://www.nowcoder.com/practice/f0db4c36573d459cae44ac90b90c6212?tpId=182&tqId=34789&ru=/exam/oj

暴力枚举就行,也可以用哈希表,哈希更省一点时间

暴力:

#include <iostream>
#include <string>
using namespace std;
int main() {
	string s;
	string t;
	getline(cin, s);
	getline(cin, t);
	string ret;
	for (int i = 0; i < s.size(); ++i)
	{
		int flag = 1;
		for (int j = 0; j < t.size(); ++j)
		{
			if (s[i] == t[j])
				flag = 0;
		}
		if (flag)
			ret += s[i];
	}
	cout << ret << endl;
	return 0;
}

哈希:

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s, t;
	getline(cin, s);
	getline(cin, t);
	bool hash[300] = { 0 };
	for (char ch : t) hash[ch] = true;
	string ret;
	for (auto ch : s)
	{
		if (!hash[ch])
		{
			ret += ch;
		}
	}
	cout << ret << endl;
	return 0;
}

2.两个链表的第一个公共结点

链接icon-default.png?t=N7T8https://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?tpId=13&tqId=11189&ru=/exam/oj

我的思路是找出长度差值,然后让长的先走差值步数,这样就可以让他们同时出发,当第一次head1 == head2时,就可以返回了,如果遍历到nullptr了,那就表示无公共。

class Solution {
public:
	ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
		int size1 = 0;
		int size2 = 0;
		ListNode* cur1 = pHead1;
		ListNode* cur2 = pHead2;
		while (cur1)
		{
			size1++;
			cur1 = cur1->next;
		}
		while (cur2)
		{
			size2++;
			cur2 = cur2->next;
		}
		int dif = abs(size1 - size2);
		cur1 = pHead1;
		cur2 = pHead2;
		if (size1 > size2)
			while (dif--)
				cur1 = cur1->next;
		if (size2 > size1)
			while (dif--)
				cur2 = cur2->next;
		while (cur1 || cur2)
		{
			if (cur1 == cur2)
				return cur1;
			cur1 = cur1->next;
			cur2 = cur2->next;
		}
		return nullptr;
	}
};

3.mari和shiny

链接icon-default.png?t=N7T8https://ac.nowcoder.com/acm/problem/26226

我做的题目太少了,最多就做过两个状态的dp,结果就没有考虑dp方面。

正解为多(3)状态dp问题,处理好初始化细节就可以。

定义三个状态:

s[i] : 前 i 个数有几个s。

h[i] :前 i 个数有几个sh。

y[i] : 前 i 个数有几个shy。

s【i】:

三种状态均可以分两种情况写状态转移方程。

若第i个位置为 h 或者 y ,则需要加上前面的 s 或者 sh 个数:
比如前i - 1个位置有n个s,

则第i个位置的sh个数则为(i - 1位置的sh个数)加上(i - 1位置的s个数 * 1个h)。

以此类推y状态。

核心dp:

#include <iostream>
#include <string>
using namespace std;
#define int long long
const int N = 3e5 + 10;
int s[N];
int h[N];
int y[N];
char str[N];

signed main() {
    int n;
    cin >> n;
    
    for(int i = 0; i < n;++i)
    {
        cin >> str[i];
    }
    
    s[0] = str[0] == 's' ? 1 : 0;
    h[0] = y[0] = 0;
    for(int i = 0; i < n; ++i)
    {
        if(str[i] == 's')
            s[i] = s[i - 1] + 1;
        else
            s[i] = s[i - 1];
        
        if(str[i] == 'h')
            h[i] = s[i - 1] + h[i - 1];
        else
            h[i] = h[i - 1];
        
        if(str[i] == 'y')
            y[i] = h[i - 1] + y[i - 1];
        else
            y[i] = y[i - 1];
    }
    
    cout << y[n - 1] << endl;
	return 0;
}
  • 21
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值