题意:给定仅包含数字且不包含0的字符串。你可以从最左开始选择连续的一段进行翻转。问:最少几步可以得到一个偶数?如果得不到一个偶数输出-1。
思路:解只有四种情况.case1:输出0,数字末尾是一个偶数不用翻转。case2:输出1,不满足case1但首位是偶数,进行整体翻转即可。case3:输出2,不满足case1和case2但只要串中含有偶数,第一步将其翻转至首位,第二部将其翻转至末尾即可。case4:输出-1,如果串中不含有偶数,无论如何翻转也不可能产生偶数。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve()
{
string s;
cin>>s;
int l=s.length();
bool flag=0;
for(int i=0;s[i];i++) {
if((s[i]-'0')%2==0){
flag=1;
break;
}
}
if(!flag){
cout<<-1<<endl;
return;
}
if((s[l-1]-'0')%2==0)
cout<<0<<endl;
else if((s[0]-'0')%2==0)
cout<<1<<endl;
else
cout<<2<<endl;
}
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--) solve();
return 0;
}
题意:四人一队每队必须至少有一个程序员和一个数学家。给出a(程序员个数)、b(数学家个数)。问:最多可以有多少符合题的队数?
思路:瓶颈问题。最多能有(a+b)/4队,而每队必须有一个a和一个b,三个放一起取最小值即为结果。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve()
{
ll a,b;
cin>>a>>b;
cout<<min(min(a,b),(a+b)/4)<<endl;
}
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--) solve();
return 0;
}
题意:给定一个数组p,每次将数组p左右最小值取出来放入新数组a,若最小值在左端点则放入a的左端,若最小值在右端点则放入a的右端。现给定a数组,问存不存在p可以得到a?如果存在输出p,如果不存在输出-1。
思路:反向模拟,每次将数组a左右最大值取出来放入数组p,若最小值在左端点则放入p的左端,若最小值在右端点则放入p的右端。至于结果不存在情况,注意到正向操作时最后取出的一定是最大值,所以若是最大值不在最左或最右,输出-1。
#include<iostream>
#include<deque>
#include<vector>
using namespace std;
typedef long long ll;
void solve()
{
int n;
cin >> n;
vector<ll>v(n + 1);
for (int i = 1; i <= n; i++) {
cin >> v[i];
}
deque<ll>d;
int l = 1, r = n;
//特判-1
if (n != v[l] && n != v[r]) {
cout << -1 << endl;
return;
}
//利用双端队列deque模拟
while (l <= r)
{
if (v[l] >= v[r]) {
d.push_front(v[l++]);
}
else {
d.push_back(v[r--]);
}
}
for (auto i : d) {
cout << i << ' ';
}
cout << endl;
}
int main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--) solve();
return 0;
}
题意:给定一棵树的结点关系,以及从根到任一结点的路径长度关系(从小到大排列)。问:满足此关系的权值分配是否存在。如果存在输出任意一组结果,否则输出-1。
思路:按照路径长度关系每次自增赋值。注意:1、如果最小值不是树根无解。2、如果当前结点正在被赋值,但它的父亲结点未被赋值则无解。因为到孩子的路径长度一定长于到父亲的路径长度。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve()
{
ll n,root;
cin>>n;
vector<ll>fa(n+1),rk(n+1),ans(n+1,-1),c(n+1,0);
for(int i=1;i<=n;i++) {
cin>>fa[i];
if(fa[i]==i) root=i;
}
bool flag=1;
for(int i=1;i<=n;i++){
cin>>rk[i];
if(rk[1]!=root) flag=0;
}
if(!flag){//最小值不是根
cout<<-1<<endl;
}
else
{
ll cnt=0;
ans[root]=0;
for(int i=2;i<=n;i++) {
int k = rk[i];
if(ans[fa[k]]==-1){//当前结点的父亲未被更新
flag=0;
break;
}
else{
ans[k] = ++cnt;
c[k]=ans[k]-ans[fa[k]];//答案即为此点路径长度减去到父亲的路径长度
}
}
if(!flag){
cout<<-1<<endl;
}
else{
for(int i=1;i<=n;i++) {
cout<<c[i]<<' ';
}
cout<<endl;
}
}
}
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--) solve();
return 0;
}