每日一题dive2-week14

加一

 思路:

开始没多想直接用栈写了个简单的逻辑,一试,超时

栈超时代码

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
stack<long long int>zanshi3;
int main() {
	int x;
	cin >> x;
	for (int e = 0; e < x; e++) {
		long long int b;
		string a;
		cin >> a >> b;
		for (int i = 0; i < b; i++) {
			cout << i << endl;
			while (a.size() != 0) {
				long long int zanshi = a.back() - '0';
				zanshi += 1;
				zanshi3.push(zanshi);
				a.resize(a.size() - 1);
			}
			while (!zanshi3.empty()) {
				if (zanshi3.top() >= 10) {
					int zs3 = zanshi3.top();
					a += zs3 % 10 + '0';
					zs3 /= 10;
					a += zs3 + '0';
				}
				else {
					a += zanshi3.top() + '0';
				}
				zanshi3.pop();
			}
			cout << a << endl;
		}
		cout << a.size() % 1000000007 << endl;
	}

}

感觉栈 进栈出太复杂,直接换成对string数组进行操作,还是超时

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
stack<long long int>zanshi3;
int main() {
	int x;
	cin >> x;
	for (int e = 0; e < x; e++) {
		long long int b;
		string a,c;
		cin >> a >> b;
		for (int i = 0; i < b; i++) {
			for (int h = 0; h < a.size(); h++) {
				int zs3 = a[h] - '0';
				zs3 += 1;
				if (zs3 >= 10) {
					c += zs3 % 10 + '0';
					zs3 /= 10;
					c += zs3 + '0';
				}
				else {
					c += zs3 + '0';
				}
			}
			a = c;
			c.clear();
		}
		cout << a.size() % 1000000007 << endl;
	}

}

果然还是我想的太简单,最后试着用模拟,

先建立一个三维数组x[10][2e9][10],用来计算0-9这几个数每个数加一了n次之后得到的数包含数字0-9的数量,

比如9,加一一次之后成了10,包含一个1和一个0,所以x[9][1][0]=1,x[9][1][1]=1;以这个逻辑进行计算.

先手动录入0-9加一一次后的结果包含数字0-9的情况

之后用循环为之后空余的位置填入数据

for (int e = 0; e <= 9; e++) {//最外层0-9循环
		for (int i = 1; i <= 2e5; i++) {//加一第n次
			for (int c = 0; c < 10; c++) {//循环遍历x[e][i]下的0-9
				for (int d = 0; d < 10; d++) {//x[e][i+1]每个0-9对应的大小应该加上x[c][1]的结果乘上x[e][i][c]的数量
					x[e][i + 1][d] += x[c][1][d] * x[e][i][c];
					x[e][i + 1][d] %= 1000000007;
				}
			}
		}
	}

之后就是轻松简单的接收数据然后获取数据每位数字对应结果的大小,相加,%1000000007,输出,结束

还有个问题就是,用cin和cout会超时,所以建议用scanf和printf

下面附上完整代码

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
long long int x[10][200005][10];
int main(){
	int n1;
	scanf("%d", &n1);
	for (int e = 0; e < 9; e++) {
		x[e][1][e + 1] = 1;
	}
	x[9][1][1] = 1;
	x[9][1][0] = 1;
	for (int e = 0; e <= 9; e++) {
		for (int i = 1; i <= 2e5; i++) {
			for (int c = 0; c < 10; c++) {
				for (int d = 0; d < 10; d++) {
					x[e][i + 1][d] += x[c][1][d] * x[e][i][c];
					x[e][i + 1][d] %= 1000000007;
				}
			}
		}
	}
	for (int f = 0; f < n1; f++) {
		long long int  n, m;
		scanf("%lld%lld", &n, &m);
		long long int jishu = 0;
		while (n) {
			int z = n % 10;
			n /= 10;
			for (int i = 0; i < 10; i++) {
				jishu += x[z][m][i];
				jishu %= 1000000007;
			}
		}		
		printf("%lld\n", jishu);
	}
}

跳跳

 思路:

开始还在想要怎么做,看着很复杂,有没有什么高深的算法,结果一看数据顶天了也超不了时,直接暴力,用map记录数据,遍历一遍,对两点坐标差除以最大公约数之后录入,最后输出map的size,结束.

需要注意的是,如果差值里面有0,需要额外提取出来单独录进去

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
vector<pair<int, int>>zuobiao;
map<pair<int ,int>,int>a;
int GCD(int a, int b)
{
	return b == 0 ? a : GCD(b, a % b);
}
int main() {
	int x;
	scanf("%d",&x);
	for (int e = 0; e < x; e++) {
		int x1, x2;
		scanf("%d%d", &x1, &x2);
		zuobiao.push_back(make_pair(x1, x2));
	}
	for (int e = 0; e < zuobiao.size(); e++) {
		for (int e1 = 0; e1 < zuobiao.size(); e1++) {
			if (e1 == e) {
				continue;
			}
			else {
				int x1 = zuobiao[e].first-zuobiao[e1].first;
				int x2 = zuobiao[e].second-zuobiao[e1].second;
				//cout << x1 << " " << x2 << endl;
				if (x1 == 0) {
					if (x2 > 0) {
					a.insert(make_pair(make_pair(0, 1),1));
					}
					else {
						a.insert(make_pair(make_pair(0, -1),1));
					}
				}
				else if(x2==0) {
					if (x1 > 0) {
						a.insert(make_pair(make_pair(1, 0),1));
					}
					else {
						a.insert(make_pair(make_pair(-1, 0),1));
					}
					
				}
				else {
					int gys=GCD(abs(x1),abs(x2));
					a.insert(make_pair(make_pair(x1 / gys, x2 / gys),1));
				}
			}
		}
	}
	cout << a.size() << endl;
}

异或和或

思路:

开始先来捋一下这个题给了些什么条件,

首先,按位异或就是,两者相同为0,不同为1,或就是两者有1就是1,全是0才是0

因此可以得出结论

//抓1 1的话,x=0,y=1;
//抓1 0的话,x=1,y=1;
//抓0 1的话,x=1,y=1;

再深思一下就会发现,只要字串力有一个1,就可以把整个字符串全部变成1,之后想变成什么都可以
,所以只要两个字符串都有1,或者两个字符串都没1,这时两者就相等 

先摆出来一个lj代码,好不容易写的而且过了,丢了心疼(恼)

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
//抓1 1的话,x=0,y=1;
//抓1 0的话,x=1,y=1;
//抓0 1的话,x=1,y=1;
//只要字串力有一个1,就可以把整个字符串全部变成1,之后想变成什么都可以
//所以只要两个字符串都有1,或者两个字符串都没1,这时两者就可能相等
int main() {
	int x;
	cin >> x;
	for (int e = 0; e < x; e++) {
		string a, b;
		cin >> a >> b;
		if (a.size() != b.size()) {
			printf("%s\n", "NO");
		}
		else {
			int a1 = 0;
			for (int i = 0; i < a.size(); i++) {
				if (a[i] - '0' == 1) {
					a1 += 1;
					if (a1 == 2) {
						break;
					}
				}
			}
			int panduan = 1;
			int b0 = 0;
			for (int i = 0; i < b.size(); i++) {
				b0 += b[i] - '0';
			}
			for (int i = 0; i < a.size(); i++) {
				if (a[i] != b[i]) {
					if (a[i] - '0' == 1) {
						if (b0 == 0) {
							printf("%s\n", "NO");
							panduan = 0;
							break;
						}
						if (a1 > 0) {
							
						}
						else {
							printf("%s\n", "NO");
							panduan = 0;
							break;
						}
					}
					else {
						if (a1 > 0) {

						}
						else {
							printf("%s\n", "NO");
							panduan = 0;
							break;
						}
					}
				}
			}
			if (panduan == 1) {
			printf("%s\n", "YES");
			}
		}
	}
}

接下来是优化以后的代码

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
int main() {
	int x;
	cin >> x;
	for (int e = 0; e < x; e++) {
		string a, b;
		cin >> a >> b;
		if (a.size() != b.size()) {
			cout << "NO" << endl;
			continue;
		}
		int a1 = 0, b1 = 0;
		for (int i = 0; i < a.size(); i++) {
			if (a[i] - '0' == 1)a1++;
			if (b[i] - '0' == 1)b1++;
		}
		if (a1 && b1 || a1 == b1) {
			cout << "YES"<< endl;
		}
		else {
			cout << "NO" << endl;
		}
	}
}

01序列

思路:

超时做法,直接遍历

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
int main() {
	int x;
	string y;
	cin >> x >> y;
	int kk = 0;
	int panduan = 1;
	for (int e = 0; e < y.size(); e++) {
		int geshu = 0;
		for (int i = e; i < y.size(); i++) {
			if (y[i]-'0' == 1) {
				geshu++;
			}
			if (geshu == x) {
				kk++;
			}
			if (geshu == x+1) {
				break;
			}
		}
	}
	cout << kk;
}

 因为直接遍历会超时,所以我们需要找一些规律,分为x=0和x!=0;

当x等于0的时候,子序列的数量为子序列长度*(子序列长度+1)/2;

当x!=0时,我们需要找到一个子序列,子序列需要包含x个1,然后我们找到最前面一个一之前的零和最后一个一后面的零的数量分别加一然后乘起来,然后找到所有包含x个1+的子序列,全部加起来,就是答案.

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
int main() {
	int x;
	string y;
	cin >> x >> y;
	int kk = 0;
	int panduan = 1;
	if (x == 0) {
		long long int ans = 0;
		for (int e = 0; e < y.size(); e++) {
			if (y[e] - '0')continue;
			int j = e;
			long long int geshu = 0;
			while (j<y.size()&&y[j] - '0' == 0) {
				j++;
				geshu++;
			}
			ans += (geshu + 1) * geshu / 2;
			e = j;
		}
		cout << ans;
		return 0;
	}
    int res = 0,cnt=0;
    for (int i = 0, j = 0; i < y.size(); i++)
    {
        while (j < y.size())
        {
            if (y[j] == '1')
                cnt++;
            if (cnt == x)
                break;
            j++;
        }
        if (cnt == x)
        {
            int ed = j + 1;
            while (ed < y.size() && y[ed] != '1')
                ed++;
            int c = ed - j;
            while (i < y.size() && y[i] != '1')
            {
                i++;
                res += c;
            }
            res += c;
            j++;
            cnt--;
        }
    }
    cout << res << endl;
}

出栈顺序判断

思路:

不能直接用栈,直接用栈操作会超时,得用模拟的法子.遍历一遍,循环用来遍历序列,单独int一个变量负责模拟push,单独int一个变量模拟栈如果不一样就一直push,如果一样就栈--;而且考虑到栈的规则,所以不用纠结像1423这样的情况,这是不可能出现的

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
int n,tt = 0;
int stk[100010], a[100010];
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    int num = 1;
    for (int i = 1; i <= n; i++)
    {
        while (!tt || stk[tt] != a[i])
        {
            printf("push %d\n", num);
            stk[++tt] = num;
            num++;
        }
        if (stk[tt] == a[i])
        {
            printf("pop\n");
            tt--;
        }
    }
    return 0;
}

序列维护

思路:

这个题,嘶,额,怎么说呢,开始我认为是要用链表来做,但是因为数据太大,用数字做标识符的话数组开不到那么大,所以只能用序列号做标识符,如果要用序列号做标识符的话,自己写链表,每加一个或减一个,整个后面的链表序列号都得变化,很麻烦,怎么办呢,这不有现成的嘛,直接vector一个,你让插几就插几,你让删哪个就删哪个,本来以为会卡输入输出时间,结果直接过了,挺好.

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
const long long N =1e3+5;
vector<long long int>h;
int main() {
	int n;
	cin >> n;
	for (int p = 0; p < n; p++) {
		string a;
		cin >> a;
		int x, y;
		if (a == "insert") {
			cin >> x >> y;
			h.insert(h.begin() + x, y);
		}
		else if (a == "delete") {
			cin >> x;
			h.erase(h.begin()+x-1);
		}
		else {
			cin >> x;
			cout << h[x-1] << endl;
		}
	}

}

 网格判断

思路:

这题没啥难度,就单纯if+else,for循环遍历

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
string x[30];
int main() {
	int n;
	cin >> n;
	for (int e = 1; e <= n; e++) {
		cin >> x[e];
		int x1 = 0, y1 = 0;
		int cishu2 = 0;
		char jilu2 = 'R';
		for (int i = 0; i < n; i++) {
			if (x[e][i] == 'B') {
				x1++;
			}
			else {
				y1++;
			}
			if (jilu2 == x[e][i]) {
				cishu2++;
			}
			else {
				jilu2 = x[e][i];
				cishu2 =1;
			}
			if (cishu2 > 2) {
				cout << 0;
				return 0;
			}
		}
		if (x1 != y1) {
			cout << 0;
			return 0;
		}
	}
	for (int e = 0; e <n; e++) {
		int cishu = 0;
		char jilu = 'R';
		int x1 = 0, y1 = 0;
		for (int i = 1; i <=n; i++) {
			if (x[i][e] == 'B') {
				x1++;
			}
			else {
				y1++;
			}
			if (jilu == x[i][e]) {
				cishu++;
			}
			else {
				jilu = x[i][e];
				cishu = 1;
			}
			if (cishu > 2) {
				cout << 0;
				return 0;
			}
		}
		if (x1 != y1) {
			cout << 0;
			return 0;
		}
	}
	cout << 1;
}

整齐的数组

 思路:

只需要计算每个数与最小数的差值的最大公约数即可

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 50;

int t, n;
int a[N];

int gcd(int a, int b)
{
    if(b == 0)
        return a;
    return gcd(b, a % b);
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    cin >> t;
    while(t --)
    {
        cin >> n;
        for(int i = 1; i <= n; i ++)
            cin >> a[i];
        sort(a + 1, a + n + 1);
        int ans = 0;
        for(int i = 2; i <= n; i ++)
        {
            if(a[i] == a[1]) continue;
            ans = gcd(ans, a[i] - a[1]);
        }
        if(ans) printf("%d\n", ans);
        else puts("-1");
    }
    return 0;
}

删删

 思路:

枚举26个字符,双指针跑字符串,当两边不一样时就判断两边有没有我们当前枚举的字符

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int x;
	cin >> x;
	while (x--) {
		int x2;
		string a;
		cin >> x2 >> a;
        int n, res = 1e9;
        bool flag = true;
		for (char e = 'a'; e <= 'z'; e++) {
			int ans = 0;
			flag = true;
			int qian = 0, hou = a.size() - 1;
			while (qian < hou) {
				if (a[qian] == a[hou]) {
					qian++; hou--;
				}
				else {
					if (a[qian] == e) {
						qian++;
						ans++;
					}
					else if (a[hou] == e) {
						hou--;
						ans++;
					}
					else {
						flag = false;
						break;
					}
				}
			}
			if (flag) { res = min(res, ans); }
		}
		if (res == 1e9) {
			cout << -1<<endl;
		}
		else {
			cout << res<<endl;
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唏嘘南溪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值