A
题意
键盘上有一些键坏掉了,坏掉的键按一次会出现两次,给一个按了键盘后出现的字符串,现在找出其中其中可能坏掉的键
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <stack>
#include <queue>
using namespace std;
#define mod 1e9+7
#define N 100
#define inf 0x3f3f3f3f
const double PI = atan(1.0)*4.0;
typedef long long ll;
int main()
{
std::ios::sync_with_stdio(false);
//freopen("E:\\in.txt","r",stdin);
int k;
cin>>k;
while(k--)
{ int c[500];int n=0;
string s;
memset(c,0,sizeof(c));
cin>>s;
s+='1';
int len=s.size();
for(int i=0;i<len-1;i++)
{
if(s[i]==s[i+1])i++;
else
c[s[i]]=1;
}
for(int i=1;i<=200;i++)
{
if(c[i]==1)cout<<(char)i;
}
cout<<endl;
}
}
B
题意:
n个01串,可以任意交换任意两个字符串的字符任意次,问最多能有多少个回文串。
思路:
经过我一番苦苦思索,只有一种情况是n-1:1和0的个数都为奇数,但所有的字符串的长度都是偶数。只有这种情况的时候是n-1个,剩下的情况都是n。
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <stack>
#include <queue>
using namespace std;
#define mod 1e9+7
#define N 100
#define inf 0x3f3f3f3f
const double PI = atan(1.0)*4.0;
typedef long long ll;
int main()
{
std::ios::sync_with_stdio(false);
// freopen("E:\\in.txt","r",stdin);
int k;
cin>>k;
while(k--)
{char a[51][51];int b[51];
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
b[i]=strlen(a[i]);
}
int i1=0,i0=0,y=0,z=0;
for(int i=0;i<n;i++)
for(int j=0;j<b[i];j++)
if(a[i][j]=='1')i1++;
else
i0++;
if(i1%2)y++;
if(i0%2)y++;
for(int i=0;i<n;i++)
if(b[i]%2)z++;
if(y==2&&z==0)cout<<n-1<<endl;
else cout<<n<<endl;
}
}
C
题意:
给一个数,如果两个数字相邻并且奇偶性不同,那么这两个数字可以交换位置,问交换后最小的数是多少。
思路:
只有奇偶不同的时候才能交换,说明所有奇数的相对位置是不变的,所有偶数的相对位置是不变的。
那么就将奇偶分别存在两个数组中,然后从两个数组的头开始,挑小的往d【】中存
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <stack>
#include <queue>
using namespace std;
#define mod 1e9+7
#define N 100
#define inf 0x3f3f3f3f
const double PI = atan(1.0)*4.0;
typedef long long ll;
int main()
{
std::ios::sync_with_stdio(false);
//freopen("E:\\in.txt","r",stdin);
int k;
cin>>k;
while(k--)
{ string c,a,b;
int d[300005];
cin>>c;
int len=c.size();
for(int i=0;i<len;i++)
{
if((c[i]-'0')%2)
a+=c[i];
else
b+=c[i];
}
b+='a';a+='a';
int lena=a.size();
int lenb=b.size();
int i=0,j=0;
int k=-1;
for(;i<lena;i++)
{
for(;j<lenb;j++)
{
if(b[j]<a[i])d[++k]=b[j]-'0';
else {d[++k]=a[i]-'0';break;}
}
}
for(int i=0;i<k;i++)
cout<<d[i];
cout<<endl;
// cout<<a<<endl;
// cout<<b<<endl;
}
}
D二分查找,贪心
题意:
你是一个大型企业的负责人。在你的企业当中共有n位员工为您工作,而且非常有趣的事是这个n是一个奇数(n不能被2整除)。你必须给你的员工分配工资。最初,您有s美元,而第ii个员工应得的薪水应该是l i∼r i之间的一个值。而无论怎么分配每个人的工资,你必须使得所有分配的工资的中位数最大。
不必把所有的钱都花在员工的开支上。
思路:
假设符合要求的中位数为x,首先,按右端点从小到大排序,ri的中位数即是x的上界;按左端点排序,得到x的下界为li的中位数。这个很好理解,画个数轴,基本就是那回事。。然后我们在x的上下界里二分,check所花费用是否小于等于s即可。怎么check呢?考虑贪心,对于ri<x的数,我们就取li,这样可以腾出更多的资金;对于li>x的数,我们取li,也是为了腾出更多资金;对于li~ri穿插x的数,我们先丢一起。通过刚才的判断我们可以得到放到x左边和右边的个数,现在我们遍历穿插的数,如果当前x左边的个数小于右边,那么这个数得用来放到左边,用最小的li即可;否则放到右边,用x的值即可。最后还剩一个数,那就是中位数x啦,所以判断tmp+x<=s即可。
代码:
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int N=200005;
const int mod=1e9+7;
const double eps=1e-8;
const double PI = acos(-1.0);
#define lowbit(x) (x&(-x))
struct node
{
ll l,r;
} g[N];
int n;
ll s;
bool cmp1(node a,node b)
{
return a.l<b.l;
}
bool cmp2(node a,node b)
{
return a.r<b.r;
}
node gg[N];
bool check(ll x)
{
ll tmp=0,l=0,r=0,cnt=0;
for(int i=1; i<=n; i++)
{
if(g[i].l>x)
tmp+=g[i].l,r++;
else if(g[i].r<x)
{
tmp+=g[i].l,l++;
}
else
{
gg[cnt++]=g[i];
}
}
int i=0,j=cnt-1;
while(i<j)
{
if(l<r)
tmp+=gg[i].l,l++,i++;
else
tmp+=x,r++,j--;
}
// cout<<"gg"<<endl;
return tmp+x<=s;
}
int main()
{
std::ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
cin>>n>>s;
for(int i=1; i<=n; i++)
{
cin>>g[i].l>>g[i].r;
}
sort(g+1,g+1+n,cmp2);
ll R=g[n/2+1].r;
sort(g+1,g+1+n,cmp1);
ll L=g[n/2+1].l;
ll l=L,r=R,mid,ans=L;
while(l<=r)
{
mid=(l+r)>>1;
if(check(mid))
{
l=mid+1;
ans=mid;
}
else
r=mid-1;
}
cout<<ans<<endl;
}
return 0;
}
E1
题意:
有N个人,他们都是投票的人,我们现在想的就是让这N个人都把票投给自己,第i个人有一个mi和pi指的是,如果有mi个人已经把票投给你了,那么他也会把票投给你,否则你可以花费pi让他把票投给你。为了让所有的人都把票投给你,问你需要的最少花费是多少?
思路:
E2
题意:
有N个人,他们都是投票的人,我们现在想的就是让这N个人都把票投给自己,第i个人有一个mi和pi指的是,如果有mi个人已经把票投给你了,那么他也会把票投给你,否则你可以花费pi让他把票投给你。为了让所有的人都把票投给你,问你需要的最少花费是多少?与E1的不同是测试数据量大了
F
题意:
给 n 块白木板, 高度为 ai, k 块红木板, 高度为 bi, 问在周长为 qi 的情况下, 有多少种取法使得任取任意数量的白木板和一块红木板组成两个严格递增数列, 要求红木板的高度为最大.
https://www.cnblogs.com/BakaCirno/p/11765302.html