赞
踩
这次比赛也是比较吃亏的,做题顺序出错了,先做的第三个,错在第三个数据点之后,才做的第二个(因为当时有个地方没检查出来)所以这次比赛还是一如既往地打拉了
那么就来发一下题解吧
题意:对于1<=k<=n,对于每个k其倍数下标之和一定为k的倍数
思路:直接从1赋值到n就行,也是水题一个
- #include<bits/stdc++.h>
- using namespace std;
- #define int long long
- int t;
- int n;
- signed main()
- {
- cin>>t;
- while(t--)
- {
- cin>>n;
- for(int i=1;i<=n;i++)
- {
- cout<<i<<" ";
- }
- cout<<"\n";
- }
- return 0;
- }
题意:就是给你两个数组,问你两个数组能否按照题上所说的方法相互转换得到
思路:将整个大矩阵拆成2*2的小矩阵,然后每次只要让左上角那个和下面的变成一样就可以,然后我们最后原本只需要检查最后一列和最后一行是否相同就可以(ps:我写的是逐一比较,因为比较好写)(错了一次是因为比较的时候内层循环写成n了)
- #include<bits/stdc++.h>
- using namespace std;
- #define int long long
- int t;
- int n,m;
- char a[505][505];
- char b[505][505];
- signed main()
- {
- cin>>t;
- while(t--)
- {
- cin>>n>>m;
- for(int i=1;i<=n;i++)
- {
- for(int j=1;j<=m;j++)
- {
- cin>>a[i][j];
- }
- }
- for(int i=1;i<=n;i++)
- {
- for(int j=1;j<=m;j++)
- {
- cin>>b[i][j];
- }
- }
- for(int i=1;i<=n-1;i++)
- {
- for(int j=1;j<=m-1;j++)
- {
- int cha = ((b[i][j]-'0')-(a[i][j]-'0')+3)%3;
- if(cha==1)
- {
- a[i][j]=(a[i][j]+1)%3+'0';
- a[i+1][j+1]=(a[i+1][j+1]+1)%3+'0';
- a[i+1][j]=(a[i+1][j]+2)%3+'0';
- a[i][j+1]=(a[i][j+1]+2)%3+'0';
- }
- else if(cha==2)
- {
- a[i][j]=(a[i][j]+2)%3+'0';
- a[i+1][j+1]=(a[i+1][j+1]+2)%3+'0';
- a[i+1][j]=(a[i+1][j]+1)%3+'0';
- a[i][j+1]=(a[i][j+1]+1)%3+'0';
- }
- }
- }
- int flag=1;
- for(int i=1;i<=n;i++)
- {
- for(int j=1;j<=m;j++)
- {
- if(a[i][j]==b[i][j])
- {
- continue;
- }
- else
- flag=0;
- }
- }
- if(flag==0)
- {
- cout<<"NO"<<"\n";
- }
- else
- {
- cout<<"YES"<<"\n";
- }
- }
- return 0;
- }
题意:就说有一个蛋糕 ,被分成了许多块,然后三个人对每部分的蛋糕都有一个自己的价值,但是所有块的价值总和是一定的,然后问你如何划分这个区间,才能满足每个区间都大于(tot+2)/3
思路:对六种情况分别贪心即可,先让两边的取到比sum大的位置,然后再看中间的是否比sum大,是的话就直接输出,如果都不满足,最后就只能输出-1了
- #include<bits/stdc++.h>
- using namespace std;
- #define int long long
- signed main()
- {
- int t;
- cin>>t;
-
- while(t--)
- {
- int n;
- cin >> n;
- int a[n+1], b[n+1], c[n+1];
- int sum = 0;
- for(int i = 1;i<=n;i++)
- {
- cin >> a[i];
- sum += a[i];
- }
- sum = (sum+2)/3;//题中说了上限除法
- for(int i = 1;i<=n;i++)
- {
- cin >> b[i];
- }
- for(int i = 1;i<=n;i++)
- {
- cin >> c[i];
- }
- vector<int> p1(n+5), p2(n+5), p3(n+5);//正序前缀和
- vector<int> s1(n+5), s2(n+5), s3(n+5);//倒序前缀和
- for(int i = 1; i <= n; i++)
- {
- p1[i] = p1[i-1] + a[i];
- p2[i] = p2[i-1] + b[i];
- p3[i] = p3[i-1] + c[i];
- }
- for(int i = n; i >= 1; i--)
- {
- s1[i] = s1[i+1] + a[i];
- s2[i] = s2[i+1] + b[i];
- s3[i] = s3[i+1] + c[i];
- }
- //a b c
- int i = 1, j = n;
- while(p1[i-1] < sum && i <= n)
- {
- i++;
- }
- while(s3[j+1] < sum && j >= 1)
- {
- j--;
- }
- if(i <= j && p2[j]-p2[i-1] >= sum)
- {
- cout << 1 << ' ' << i-1 << ' ' << i << ' ' << j << ' ' << j+1 << ' ' << n << endl;
- continue;
- }
- // a c b
- i = 1, j = n;
- while(p1[i-1] < sum && i <= n)
- {
- i++;
- }
- while(s2[j+1] < sum && j >= 1)
- {
- j--;
- }
- if(i <= j && p3[j]-p3[i-1] >= sum)
- {
- cout << 1 << ' ' << i-1 << ' ' << j+1 << ' ' << n << ' ' << i << ' ' << j << endl;
- continue;
- }
- // b c a
- i = 1, j = n;
- while(p2[i-1] < sum && i <= n)
- {
- i++;
- }
- while(s1[j+1] < sum && j >= 1)
- {
- j--;
- }
- if(i <= j && p3[j]-p3[i-1] >= sum)
- {
- cout << j+1 << ' ' << n << ' ' << 1 << ' ' << i-1 << ' ' << i << ' ' << j << endl;
- continue;
- }
- // b a c
- i = 1, j = n;
- while(p2[i-1] < sum && i <= n)
- {
- i++;
- }
- while(s3[j+1] < sum && j >= 1)
- {
- j--;
- }
- if(i <= j && p1[j]-p1[i-1] >= sum)
- {
- cout << i << ' ' << j << ' ' << 1 << ' ' << i-1 << ' ' << j+1 << ' ' << n << endl;
- continue;
- }
- // c a b
- i = 1, j = n;
- while(p3[i-1] < sum && i <= n)
- {
- i++;
- }
- while(s2[j+1] < sum && j >= 1)
- {
- j--;
- }
- if(i <= j && p1[j]-p1[i-1] >= sum)
- {
- cout << i << ' ' << j << ' ' << j+1 << ' ' << n << ' ' << 1 << ' ' << i-1 << endl;
- continue;
- }
- // c b a
- i = 1, j = n;
- while(p3[i-1] < sum && i <= n)
- {
- i++;
- }
- while(s1[j+1] < sum && j >= 1)
- {
- j--;
- }
- if(i <= j && p2[j]-p2[i-1] >= sum)
- {
- cout << j+1 << ' ' << n << ' ' << i << ' ' << j << ' ' << 1 << ' ' << i-1 << endl;
- continue;
- }
- cout << -1 << endl;
- }
-
- return 0;
- }
题意:就是说给你两个数组,然后每次再a数组选两个坐标,b数组选两个坐标,然后各自再各自的数组交换,然后问你最后两个数组能不能变成一样的
思路:这题我想到了两种做法
(1)逆序对的方法,众所周知,在大学有一门神奇的科目叫做线性代数,线性代数里面讲过一个东西叫做逆序对,只有逆序对的个数为同一奇偶性,才有可能相同,因为a,b数组每次都要变换一次,所以他们的奇偶性一定是都会在每一次变化,所以我们需要统计奇偶性,然后来判断,当然了,在之前还需要判断元素种类是否相同,如果个数不同一定为no
- #include<bits/stdc++.h>
- using namespace std;
- #define int long long
- int mergeSort(vector<int> &nums, int left, int right)
- {
- if (left >= right) {
- return 0;
- }
-
- int mid = left + (right - left) / 2;
- int count = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right);
-
- vector<int> tmp(right - left + 1);
- int i = left, j = mid + 1, k = 0;
-
- while (i <= mid && j <= right) {
- if (nums[i] <= nums[j]) {
- tmp[k++] = nums[i++];
- } else {
- tmp[k++] = nums[j++];
- count += mid - i + 1; // 计算逆序数
- }
- }
-
- while (i <= mid) {
- tmp[k++] = nums[i++];
- }
- while (j <= right) {
- tmp[k++] = nums[j++];
- }
-
- for (int p = 0; p < tmp.size(); ++p) {
- nums[left + p] = tmp[p];
- }
-
- return count;
- }
-
- int solve(vector<int> &nums)
- {
- if (nums.size() <= 1) {
- return 0;
- }
- return mergeSort(nums, 0, nums.size() - 1);
- }
-
- void solve()
- {
- map<int,int> mp;
- int n;
- cin >> n;
- vector<int> a(n+2);
- vector<int> b(n+2);
- for (int i=1;i<=n;i++)
- cin >> a[i];
- for (int i=1;i<=n;i++)
- {
- cin >> b[i];
- mp[b[i]]=i;
- }
- for(int i=1;i<=n;i++)
- {
- if(mp.count(a[i])==0)
- {
- cout<<"NO\n";
- return ;
- }
- }
- int ans1=solve(a),ans2=solve(b);
- if (ans1%2 ==ans2%2)
- cout << "YES\n";
- else
- cout << "NO\n";
- }
- signed main()
- {
- int t;
- cin >> t;
- while (t--)
- solve();
- return 0;
- }
(2)那么来讲另一种比较简单的方法,交换次数来判断,因为题目上所说每次两个数组都要交换,那么我们就只交换一个,然后统计变成另一个的次数为多少,是偶数就是yes是奇数就是no
当然了,在之前也是需要判断种类是否相同的
- #include <bits/stdc++.h>
- using namespace std;
- #define int long long
- int a[200005], b[200005];
- map<int, int> mp;
- void solve()
- {
- mp.clear();
- int n;
- cin >> n;
- for (int i=1;i<=n;i++)
- cin >> a[i];
- for (int i=1;i<=n;i++)
- {
- cin >> b[i];
- mp[b[i]]=i;
- }
- int ans = 0;
- for (int i=1;i<=n;i++)
- {
- if (b[i] == a[i])
- continue;
- if (mp.count(a[i]) == 0)
- {
- cout << "NO\n";
- return;
- }
- int p=mp[a[i]];
- swap(b[i],b[p]);
- mp[b[i]]=i;
- mp[b[p]]=p;
- ans+=1;
- }
- if (ans%2 == 0)
- cout << "YES\n";
- else
- cout << "NO\n";
- }
- signed main()
- {
- int t;
- cin >> t;
- while (t--)
- solve();
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。