1.美丽的2
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<bitset>
#include<vector>
using namespace std;
int main()
{
int i,j,ans=0;
for(i=1;i<=2020;i++)
{
j=i;
while(j!=0)
{
if(j%10==2)
{
ans++;
break;
}
j/=10;
}
}
cout<<ans<<endl;
return 0;
}
答案:563
2.扩散
思路:比赛时忘记了还有负数的情况,可以将整个坐标系向左、下移2020个单位,即给定的4个点的横纵坐标加上2020,然后广搜打标记即可。
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<bitset>
#include<vector>
#include<queue>
using namespace std;
struct node{
int x,y,cnt;
};
int book[7000][7000],ans=4;
int nextx[4]={-1,0,0,1};
int nexty[4]={0,1,-1,0};
int main()
{
queue<node>q;
node n1,n2;
n1.x=0+2020,n1.y=0+2020,n1.cnt=0;
q.push(n1);
book[n1.x][n1.y]=1;
n1.x=2020+2020,n1.y=11+2020,n1.cnt=0;
q.push(n1);
book[n1.x][n1.y]=1;
n1.x=11+2020,n1.y=14+2020,n1.cnt=0;
q.push(n1);
book[n1.x][n1.y]=1;
n1.x=2000+2020,n1.y=2000+2020,n1.cnt=0;
q.push(n1);
book[n1.x][n1.y]=1;
while(!q.empty())
{
n1=q.front();
q.pop();
if(n1.cnt>=2020)
continue;
for(int i=0;i<4;i++)
{
int nx=n1.x+nextx[i];
int ny=n1.y+nexty[i];
if(book[nx][ny]==0)
{
book[nx][ny]=1;
ans++;
n2.x=nx,n2.y=ny,n2.cnt=n1.cnt+1;
q.push(n2);
}
}
}
cout<<ans<<endl;
return 0;
}
答案:20312088
3.阶乘约数
思路:一开始想的用1-n的数字随意组合,看能组出多少种不同的数,但是这样会出现重复的数,而且不太好去掉。
所以想到了分解质因数,记录所有素数的个数,每种素数可以有它的个数+1种选择,即不选、选一个、选两个、...、全选,最后答案为(每种素数个数+1)的乘积。
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<bitset>
#include<vector>
#include<queue>
using namespace std;
int prime[110];
int isprime[110];
int book[110];
int main()
{
int i,j,k,num=0;
long long ans=1;
for(i=2;i<=100;i++)
{
if(isprime[i]==0)
prime[num++]=i;
for(j=0;j<num&&i*prime[j]<=100;j++)
{
isprime[i*prime[j]]=1;
if(i%prime[j]==0)
break;
}
}
for(i=2;i<=100;i++)
{
j=i;
for(k=2;k*k<=j;k++)
{
while(j%k==0&&isprime[k]==0)
{
book[k]++;
j/=k;
}
}
if(j>1)
book[j]++;
}
for(i=2;i<100;i++)
{
if(book[i]!=0)
ans*=(book[i]+1);
}
cout<<ans<<endl;
return 0;
}
答案:39001250856960000
4.本质上升序列
思路:(我觉得我的做法还是挺暴力的,半分钟内肯定能跑出来,毕竟是个填空,而且最主要的是其实我也想不出什么巧妙的算法,能拿分就是最重要的)
用一个set集合保存所有的合法序列,每遍历到一个字符,看它是否能添加在已有的序列后面,即遍历set中已存在的所有序列,别忘了每一个单独的字符也是一个合法序列。
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<bitset>
#include<vector>
#include<queue>
#include<set>
using namespace std;
set<string>s;
set<string>::iterator it;
string a,x,c;
int main()
{
cin>>a;
int i,n,m;
m=a.length();
for(i=0;i<m;i++)
{
for(it=s.begin();it!=s.end();it++)
{
x=*it;
n=x.length();
if(x[n-1]<a[i])
{
x.push_back(a[i]);
s.insert(x);
}
}
c.erase();
c.push_back(a[i]);
s.insert(c);
}
long long ans=s.size();
cout<<ans<<endl;
return 0;
}
字符串:
tocyjkdzcieoiodfpbgcncsrjbhmugdnojjddhllnofawllbhfiadgdcdjstemphmnjihecoapdjjrprrqnhgccevdarufmliqijgihhfgdcmxvicfauachlifhafpdccfseflcdgjncadfclvfmadvrnaaahahndsikzssoywakgnfjjaihtniptwoulxbaeqkqhfwl
答案:3616159
5.玩具蛇
思路:任意起点,任意终点,求不同的路线条数,4*4矩阵,深搜即可。
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<bitset>
using namespace std;
int book[10][10];
int nextx[4]={-1,1,0,0};
int nexty[4]={0,0,-1,1};
long long ans;
void dfs(int x,int y,int cnt)
{
if(cnt==16)
{
ans++;
return;
}
int i;
for(i=0;i<4;i++)
{
int nx=x+nextx[i];
int ny=y+nexty[i];
if(nx>=1&&nx<=4&&ny>=1&&ny<=4&&book[nx][ny]==0)
{
book[nx][ny]=1;
dfs(nx,ny,cnt+1);
book[nx][ny]=0;
}
}
}
int main()
{
int i,j;
for(i=1;i<=4;i++)
{
for(j=1;j<=4;j++)
{
book[i][j]=1;
dfs(i,j,1);
book[i][j]=0;
}
}
cout<<ans<<endl;
return 0;
}
答案:552
6.皮亚诺曲线距离
思路:
代码:
7.游园安排
思路:最长上升子序列的变形题,输出最长的序列,如果答案有多个,输出字典序最小的那个。
代码:
8.答疑
思路:贪心,关键看怎么排序,试了几个都不太对,最后发现是总用时少的排在前面就过了。
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<bitset>
using namespace std;
struct node{
long long a,b;
};
node m[1010];
bool cmp(node n1,node n2){
return n1.a+n1.b<=n2.a+n2.b;
}
int main()
{
int i,n;
long long x,y,z,ans=0,sum=0;
cin>>n;
for(i=0;i<n;i++)
{
cin>>x>>y>>z;
m[i].a=x+y;
m[i].b=z;
}
sort(m,m+n,cmp);
for(i=0;i<n;i++)
{
sum+=m[i].a;
ans+=sum;
sum+=m[i].b;
}
cout<<ans<<endl;
return 0;
}
9.出租车
10.质数行者
思路:直接深搜,肯定会t
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<bitset>
using namespace std;
int prime[1010],isprime[1010],num;
void init()
{
int i,j;
for(i=2;i<=1000;i++)
{
if(isprime[i]==0)
prime[num++]=i;
for(j=0;j<num&&i*prime[j]<=1000;j++)
{
isprime[i*prime[j]]=1;
if(i%prime[j]==0)
break;
}
}
}
int n,m,w,x1,y3,z1,x2,y2,z2;
long long ans;
long long mod=1000000007;
void dfs(int x,int y,int z)
{
if(x==x1&&y==y3&&z==z1||x==x2&&y==y2&&z==z2)
return;
if(x==n&&y==m&&z==w)
{
ans++;
ans%=mod;
return;
}
for(int i=0;i<num;i++)
{
if(x+prime[i]<=n)
dfs(x+prime[i],y,z);
if(y+prime[i]<=m)
dfs(x,y+prime[i],z);
if(z+prime[i]<=w)
dfs(x,y,z+prime[i]);
}
}
int main()
{
init();
cin>>n>>m>>w;
cin>>x1>>y3>>z1>>x2>>y2>>z2;
dfs(1,1,1);
cout<<ans<<endl;
return 0;
}
或者放弃大数据,记忆或搜索,只考虑300以内的数据,还能得60%的分
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<bitset>
using namespace std;
int prime[1010],isprime[1010],num;
void init()
{
int i,j;
for(i=2;i<=1000;i++)
{
if(isprime[i]==0)
prime[num++]=i;
for(j=0;j<num&&i*prime[j]<=1000;j++)
{
isprime[i*prime[j]]=1;
if(i%prime[j]==0)
break;
}
}
}
int n,m,w,x1,y3,z1,x2,y2,z2;
long long ans;
long long mod=1000000007;
int judge(int x,int y,int z)
{
if(x==x1&&y==y3&&z==z1||x==x2&&y==y2&&z==z2)
return 0;
else
return 1;
}
int f[310][310][310];
int dfs(int x,int y,int z)
{
if(x==n&&y==m&&z==w)
return 1;
if(f[x][y][z]!=-1)
return f[x][y][z];
int c=0;
for(int i=0;i<num;i++)
{
if(x+prime[i]<=n&&judge(x+prime[i],y,z))
c=(c+dfs(x+prime[i],y,z))%mod;
if(y+prime[i]<=m&&judge(x,y+prime[i],z))
c=(c+dfs(x,y+prime[i],z))%mod;
if(z+prime[i]<=w&&judge(x,y,z+prime[i]))
c=(c+dfs(x,y,z+prime[i]))%mod;
}
return f[x][y][z]=c;
}
int main()
{
init();
cin>>n>>m>>w;
cin>>x1>>y3>>z1>>x2>>y2>>z2;
memset(f,-1,sizeof(f));
cout<<dfs(1,1,1)<<endl;
return 0;
}