总体来说,这次的题目还是不错的,不过有几题竟然是原题,着实有点让人心醉...
A.偷吃糖果
Time Limit: 1000Ms
Memory Limit: 65536KB
Description
解题思路:此题思路还是简单的,因为题目明确吃糖果的策略为每次选出一盒糖果中两个连续的同种类别的糖果,然后吃掉其中一块,所以对于每一种糖果,只要一开始有,那么最终必定至少会留下一块,那么为了便于处理,我们可以将两个字符串简化,同种类别糖果只留下一块,以便于比较
例如第一组样例,rrrjj与rrrj,简化后的效果为rj与rj,很明显符合
/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<deque>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 1000 + 10;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
char a[N],b[N];
int main()
{
int t,i,k;
scanf("%d",&t);
while(t--)
{
scanf("%s%s",a,b);
k=0;
a[k++]=a[0];
for(i=1;a[i]!='\0';i++)
if(a[i]==a[i-1])
continue;
else
a[k++]=a[i];
a[k++]='\0';
//puts(a);
k=0;
b[k++]=b[0];
for(i=1;b[i]!='\0';i++)
if(b[i]==b[i-1])
continue;
else
b[k++]=b[i];
b[k++]='\0';
//puts(b);
if(strcmp(a,b))
puts("No");
else
puts("Yes");
}
return 0;
}
解题思路:求[a,b]区间内与n互质的数的个数,我们可以转化为[1,b]内与n互质的数的个数减去[1,a-1]内与n互质的数的个数
而要求[1,b]内与n互质的数的个数,我们可以很自然地想到容斥原理
求解区间[a,b]中与k互质的个数
首先对k进行质数分解,然后与这个因子GCD!=1则共有n/ki个
有计算重复的部分,因此利用 容斥原理: k1+k2+k3-k1*k2-.....求出与k不互质的个数,用总的减去即可
然后blabla,就是单纯的容斥原理模板题,话说此题就是一道原题,hdu4135
/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<deque>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
#define ll long long
using namespace std;
const int N = 20 + 10;
const int M = 10000 + 10;
const int inf = 100000000;
const int mod = 2009;
int k,prime[N];
ll factor[M];
void get_prime(ll n)
{
k=0;
for(ll i=2;i*i<=n;i++)
if(n%i==0)
{
prime[k++]=i;
while(n%i==0)
n/=i;
}
if(n>1)
prime[k++]=n;
}
ll Exclusion(ll n)
{
int i,j,p=0,q;
ll sum=0;
factor[p++]=-1;
for(i=0;i<k;i++)
{
q=p;
for(j=0;j<q;j++)
factor[p++]=factor[j]*prime[i]*(-1);
}
for(i=1;i<p;i++)
sum+=n/factor[i];
return sum;
}
int main()
{
int t;
ll a,b,n;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld%lld",&a,&b,&n);
get_prime(n);
printf("%lld\n",b-Exclusion(b)-(a-1-Exclusion(a-1)));
}
return 0;
}
解题思路:据说是莫比乌斯反演,不过本人并没有搞出来,看看日后会不会更它,主要看我懒不懒
此处暂时放上一种AC的代码
#include<stdio.h>
#include<math.h>
#define LL long long
#define MAXN 100010
LL C[MAXN]={0};
void Init(){
C[1]=C[2]=0;
LL i,j;
for(i=3;i<MAXN;i++)
C[i]=i*(i-1)*(i-2)/6;
}
LL digui(int N){
if(N<3)
return 0;
if(N==3)
return 1;
int i;
LL sum;
for(i=2,sum=0;i<N;i++){
if(N/i>=3){
sum+=digui(N/i);
}
}
return C[N]-sum;
}
int main(){
int T;
int N,M;
scanf("%d",&T);
Init();
while(T--){
scanf("%d%d",&N,&M);
if(N/M<3)
printf("0\n");
else{
printf("%lld\n",digui(N/M));
}
}
return 0;
}
解题思路:不得不说,这是第二道原题,有印象的同学必定会记得"最少拦截系统",不过hdu的数据就有点水了,不是正解
我的做法是用STL set来模拟,因为set会自动帮我们排序,而每次进来的数,要找比当前进来的数小的最大数进行更新,如果不存在则插入一个新的,最终set的大小size()就是题目要求的结果
/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<deque>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
#define ll long long
using namespace std;
const int N = 20 + 10;
const int M = 10000 + 10;
const int inf = 100000000;
const int mod = 2009;
set<int> s;
set<int>::iterator it1,it2;
int main()
{
int t,x,n,i;
scanf("%d",&t);
while(t--)
{
s.clear();
scanf("%d",&n);
scanf("%d",&x);
s.insert(x);
for(i=1;i<n;i++)
{
scanf("%d",&x);
it2=s.upper_bound(x);
it1=it2;
it1--;
if(it2==s.begin())
s.insert(x);
else
{
s.erase(it1);
s.insert(x);
}
}
printf("%d\n",s.size());
}
return 0;
}
解题思路:首先,我们已经知道了B的最高位数字为n,那么我们就可以来模拟一下除法的过程
就拿样例来举例子
我们每一轮除法得到的商会作为下一轮的被除数,当然,不能忘了考虑上一轮因为除不尽留下的余数,就这样一直计算到被除数s[i]能被除数k整除且商为n的时候结束
除了n=0,k=0时,B=0
其他k=0的时候,B=-1(无解)
由上述方法算出的结果还让我错了一次
例如n=1,k=2时,B=105263157894736842,那么A=052631578947368421,很显然,这样是不对的,移动前的A不可能含有前导0,所以我们还要判断当B的位数>=2时,从高到低来看,第二位不能为0,否则也是无解的情况
/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<deque>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
#define ll long long
using namespace std;
const int N = 10000 + 10;
const int M = 10000 + 10;
const int inf = 100000000;
const int mod = 2009;
int ans[N],s[N];
int main()
{
int t,n,k,p,i,c;
scanf("%d",&t);
while(t--)
{
i=p=c=0;
scanf("%d%d",&n,&k);
if(!n&&!k)
{
puts("0");
continue;
}
if(!k)
{
puts("-1");
continue;
}
s[i]=n;
while(!((s[i]+c)%k==0&&(s[i]+c)/k==n))
{
ans[p]=(s[i]+c)/k;
c=((s[i]+c)%k)*10;
i++;
s[i]=ans[p];
p++;
}
if(s[1]==0&&p>=2)
{
puts("-1");
continue;
}
for(i=0;i<=p;i++)
printf("%d",s[i]);
puts("");
}
return 0;
}
H.谁才是最强战舰!
Time Limit: 1000MS
Memory Limit: 65536KB
Description
解题思路:很显然,这是一道博弈题,而且是尼姆博弈的变型,谁拿完谁输,本人还是用了模板,有兴趣学习一下尼姆博弈的可以点此链接->尼姆博弈
/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<deque>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 100000 + 10;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
long long h[N],w[N];
int main()
{
int t,x,ans,n,i,c;
int num1,num2;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
ans=num1=num2=0;
for(int i=0;i<n;i++)
{
scanf("%d",&x);
if(x==1)
num1++; //孤单堆
else
num2++; //充裕堆
ans^=x;
}
if((ans&&num2!=0)||(!ans&&num2==0)) //S1,S2,T0必胜
puts("Yamato_Saikou!");
else //S0,T2必败
puts("Meidikeji_Shijiediyi!");
}
return 0;
}
J.water1
Time Limit: 1000MS
Memory Limit: 65536KB
Description
解题思路:题目告诉我们'+'的高度和宽度,要我们填'w',最顶层需要一层的'w',问需要多少个'w'
题目明确当N=0时,ans=1;
所以我们只需要找到最大海拔值Max+1
那么最终所需要的'w'个数即为
ans+=(Max-h[i])*w[i];
此题一开始着实被__int64坑了一把,该网站仅支持long long,而且输入输出的时候还得用%lld,不然竟然是Presentation Error,这就不能忍了,凭什么不是Wrong Answer!!!好吧,此题会超int
/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<deque>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 100000 + 10;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
long long h[N],w[N];
int main()
{
int n,i;
long long ans,Max;
while(~scanf("%d",&n))
{
Max=ans=0;
for(i=0;i<n;i++)
{
scanf("%lld%lld",&h[i],&w[i]);
Max=max(Max,h[i]);
}
Max++;
for(i=0;i<n;i++)
ans+=(Max-h[i])*w[i];
long long s=1;
printf("%lld\n",max(ans,s));
}
return 0;
}
菜鸟成长记