A题:
题意: 两人博弈,每次一个人从一堆中拿 k 个,同时从另一堆拿 k * s(s >= 0) 个,问谁先不能拿。
10000 组数据,N <= 5000
解题思路:暴力模拟 推理得:A一次能直接拿完A赢 拿不完B赢
代码:
#include
#include
#include
#include
#include
#include
using namespace std;
#define N 5010
bool ans[N][N];
void pre_work(){
//赋初值
ans[0][0]=0;
//穷举 一次能拿完的话A赢 不然B赢
for(int i=0;i<=5000;i++){
for(int j=0;j<=5000;j++){
//已经被赋值 跳过
if(ans[i][j]==1)continue;
//一堆取k个 另一堆取k*l 穷举
for(int k=1;k+i<=5000;k++){
for(int l=0;l*k+j<=5000;l++){
ans[k+i][l*k+j]=1;
}
}
//从第二堆取k个 从第一堆取k*l个
for(int k=1;k+j<=5000;k++){
for(int l=0;l*k+i<=5000;l++){
ans[l*k+i][k+j]=1;
}
}
}
}
}
int main(){
pre_work();
int t;
cin>>t;
while(t--){
int n,m;
cin>>n>>m;
if(ans[n][m]==1)cout<<"Alice"<
B题:球卡在了梯形内,求卡住的高度是多少?
思路:数学推理,将梯形补成三角形,根据两次相似求得高度;
代码:
#include
#include
#include
#include
using namespace std;
#define eps 1e-7;
int main(){
double a,r,b,h,x,l,j;
cin>>r>>a>>b>>h;
if(b>2*r){
//掉下去
cout<<"Drop"<
D:题意:给出一个 n*n 的 01 矩阵,要用一个 1*m 的矩阵去覆盖一段 0,求方案数。
解题思路:1)将两个字符数组储存,利用kmp算法进行匹配,累加每一行的答案;
代码:
KMP算法:
#include
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
char str[maxn],mo[maxn];
int Next[maxn];
void getNext(){
Next[0]=-1;
int len=strlen(mo),k=-1;
for(int i=1;i-1&&mo[k+1]!=mo[i])k=Next[k];
if(mo[k+1]==mo[i])k++;
Next[i]=k;
}
}
int Kmp(){
getNext();
int len1=strlen(str),len2=strlen(mo),k=-1,ans=0;
for(int i=0;i-1&&mo[k+1]!=str[i])k=Next[k];
if(mo[k+1]==str[i])k++;
if(k==len2-1){
k=Next[k];
ans++;
}
}
return ans;
}
char M[2005][2005];
int main(){
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",&M[i]);
}
int ans=0;
scanf("%s",&M[0]);
for(int i=0;i
暴力模拟:
#include
#include
using namespace std;
typedef long long ll;
int main(){
int n,m;
cin>>n>>m;
ll ans=0;
for(int i=0;i>s;
for(int j=0;j
F题:
题意:定义一个自然数是 3-friendly 的,如果它存在一个子串(允许前导0)是 3 的倍数。多组数据,求 L~R 中 3-friendly 的数的个数。
解题思路:推理得:三位数及以上一定是,个位数打表,两位数暴力,利用前缀和速度求解。
代码:
#include
using namespace std;
typedef long long ll;
ll dp[105]={0,0,0,1,1,1,2,2,2,3}; //前缀和数组 个位数直接打表
ll t,lef,rig;
ll ans(ll x){
if(x<=99) return dp[x];
//推理得 三位数及以上 一定满足条件 返回个数加之前的
else return x-99+dp[99];
}
int main(){
for(int i=10;i<=99;i++){
if(i%10%3==0||i/10%3==0||i%3==0){
//判断是否满足条件 个位数 十位数 整体
dp[i]=dp[i-1]+1;
}else{
dp[i]=dp[i-1];
}
}
cin>>t;
while(t--){
cin>>lef>>rig;
cout<