B
题目链接
http://acm.hust.edu.cn/vjudge/problem/24840
题意
给出一个天枰的文字描述,问最少修改多少次可以使天枰的所有支点都是平衡的。
题解
找一个基准(depth*weigh),把其他所有的重量的基准都修改为这个值,那么只要这个基准的出现次数最多,那么修改的次数也就越少。sum-基准次数。
代码
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<string>
#include<cctype>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
int main()
{
int t;
scanf(
"%d",&t);
while(t--)
{
string st;
cin>>st;
int n=st.size();
int cnt1=
0,cnt2=
0;
map<long long,int>num;
int cnt3=
0;
for(
int i=
0;i<n;i++)
{
if(st[i]==
'['){cnt1++;cnt2++;}
else if(
isdigit(st[i]))
{
long long numm=st[i]-
'0';
i++;
while(
isdigit(st[i])){
numm=numm*
10+st[i]-
'0';
i++;
if(i>=n){
break;}
}
i--;
long long aa=
1;
for(
int j=
0;j<cnt1;j++)aa*=
2;
numm*=aa;
num[numm]++;
cnt3++;
}
else if(st[i]==
']')cnt1--;
}
map<long long,int>::iterator it=num.begin();
int ans=-
1;
for(;it!=num.end();it++)
{
ans=max(ans,it->second);
}
if(cnt2==
0)
printf(
"0\n");
else printf(
"%d\n",cnt3-ans);
}
return 0;
}
C
题目链接
http://acm.hust.edu.cn/vjudge/problem/22883
题意
切披萨,问n刀下去,披萨可以被切成几块。
题解
ans=1+((n+1)*n)/2;
D
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=4334
题意
给出5个数的集合,问能否从每个集合中选出一个数,使5个数之后等于0。
题解
先把前两个集合的数的和依次求出来,得到新集合n1,然后同样处理第三第四个集合得到新集合n2,遍历第五个集合中的每个元素x,n=n1+x,二分查找在n2集合中是否存在n的相反数。
代码
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<string>
#include<cctype>
#include<algorithm>
#include<vector>
using namespace std;
long long a[
7][
300];
int main()
{
int t;
scanf(
"%d",&t);
while(t--)
{
for(
int i=
0;i<
7;i++)
for(
int j=
0;j<
300;j++)a[i][j]=
0;
int n;
scanf(
"%d",&n);
for(
int i=
0;i<
5;i++)
for(
int j=
0;j<n;j++)
scanf(
"%lld",&a[i][j]);
vector<long long>s1;
vector<long long>s2;
for(
int i=
0;i<n;i++)
{
for(
int j=
0;j<n;j++)
{
long long t=a[
0][i]+a[
1][j];s1.push_back(t);
}
}
for(
int i=
0;i<n;i++)
{
for(
int j=
0;j<n;j++)
{
long long t=a[
3][i]+a[
4][j];s2.push_back(t);
}
}
sort(s1.begin(),s1.end());
sort(s2.begin(),s2.end());
int ok=
0;
for(
int i=
0;i<n;i++)
{
for(
int j=
0;j<s1.size();j++)
{
long long t=a[
2][i]+s1[j];
int op=lower_bound(s2.begin(),s2.end(),-t)-s2.begin();
if(s2[op]+t==
0){ok=
1;
break;}
}
if(ok==
1)
break;
}
if(ok==
1)
printf(
"Yes\n");
else printf(
"No\n");
}
return 0;
}
F
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=4346
题意
只要存在i位置为R,j位置也为R,并且(i+j)/2位置为G,那么这条路就是美丽的,问最多可以构造出多少条美丽的路。
题解
正面构造感觉特别难,不能把所有情况按某种思路一次找出来。所有就反着来了,美丽的串=总的串数-不美丽的串。而不美丽的串,首先满足条件,相邻的两个R之间的距离为奇数,易得。其次,所有的R之间的距离应该是相同的。反正法,假如R1,R2,R3,R1与R2之间的距离不等于R2与R3之间的距离,因为奇数+奇数=偶数,那么R1与R3之间距离是偶数,存在(R1+R3)/2点,但这个点不是R2,是G,所有事美丽串,与条件矛盾。简而言之就是R1与R3中间的判断点一个要是个R。 然后就好了,遍历R的起点,遍历所有奇数距离,判定是否所有的R都满足不美丽串条件,最后total-unbea。
代码
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<string>
#include<cctype>
#include<algorithm>
#include<vector>
using namespace std;
const long long mod=
1e9+
7;
int main()
{
std::ios::sync_with_stdio(
false);
int t;
cin>>t;
while(t--)
{
string st;
cin>>st;
int unknow=
0,r_num=
0;
for(
int i=
0;i<st.size();i++)
{
if(st[i]==
'R')r_num++;
if(st[i]==
'?')unknow++;
}
int n=st.size();
long long unbea=
0;
if(r_num==
0)unbea++;
for(
int i=
0;i<n;i++)
{
if(st[i]==
'R'||st[i]==
'?')
{
int zz=
0;
if(st[i]==
'R')zz=
1;
if(zz==r_num){unbea=(unbea+
1)%mod;}
for(
int j=
1;j+i<n;j+=
2)
{
int z=zz;
for(
int k=i+j;k<n;k+=j)
{
if(st[k]==
'R')z++;
if(st[k]==
'G')
break;
if(z==r_num){unbea=(unbea+
1)%mod;}
}
}
}
}
long long cc=
1;
for(
int i=
0;i<unknow;i++){cc=(cc*
2)%mod;}
long long ans=cc-unbea;
cout<<ans<<endl;
}
return 0;
}
G
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=4371
题意
一个博弈问题,一个人x开始写0=s1,然后另外一个人y任选一个数加上去得到s2,然后x可以有两个选择,一个在n的基础上可以任意加一个数得到s3,s3不能大于n,或者任意减一个数得到s3,但减的时候s3>s1,即s3必须大于前前个数。当一个人无法操作时,即认输。
题解
一个贪心的博弈,首先我们排除选大的数的情况- -,因为你选大数,别人就选小的数求差,那么你就只能一直选大的数,直到最后输。这个游戏是由最小的数和上限来决定输赢的,上限/最小的数=奇数,则Alice赢,偶数则Bob赢。上面已经分析了,选大数一点赢的希望都没有,那就只有选最小的数,两个人都一直选最小的数,知道最后一个人没办法选了,决出胜负。
代码
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<string>
#include<cctype>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
int t;
scanf(
"%d",&t);
for(
int i=
1;i<=t;i++)
{
int n,m;
scanf(
"%d%d",&n,&m);
int minx=
1e9+
9;
for(
int j=
0;j<m;j++)
{
int z;
scanf(
"%d",&z);
minx=min(minx,z);
}
int t=n/minx;
if(t%
2==
1)
printf(
"Case #%d: Bob\n",i);
else printf(
"Case #%d: Alice\n",i);
}
return 0;
}
转载请注明原文地址: https://ju.6miu.com/read-1303346.html