1-M-本题主要考察了找规律
思路:背包。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100005;
int main()
{
int t,n,m;
cin>>n>>m;
double dp[550][550];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
for(int k=0;k<=j;k++)
{
dp[i][j]=max(dp[i-1][j-k]+(double)1.0*k/j,dp[i][j]);
}
}
}
printf("%.9lf",dp[n][m]);
}
2-H-Tokitsukaze and K-Sequence
思路:当数字出现的次数sum>k时无论怎么分组最多都只能满足k-1,sum<=k时则子序列之和加sum,用map统计出现i次的有几个数字。(用map排序会超时(),只有70%。)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
int n,a[100005];
while(t--)
{
cin>>n;
int s=0;
map<int,int>m,b;
for(int i=1;i<=n;i++)
{
cin>>a[i];
b[a[i]]++;
}
for(auto&[x,y]:b)
{
// cout<<b[a[i]]<<" ";
m[y]++;//出现y次的有几个.
}
//cout<<endl;
/*for(auto&[x,y]:b)
{
cout<<x<<" "<<m[y]<<" ";
}*/
ll k=0;
for(int i=1;i<=n;i++)
{
k=0;
for(auto&[x,y]:m){
if(x>i)k+=y*(i-1);//出现了x次,有y个.
else k+=x*y;
}
cout<<k<<endl;
}
}
}
2-F-Tokitsukaze and Gold Coins (easy)
思路:从起点搜到终点再倒回起点,经过两遍的即为可拿到金币的最大值。(好像会卡memset。)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+10;
int a[maxn][3],b[maxn][3],c[maxn][3];
int n,k,x,y;
void dfs(int x,int y)
{
a[x][y]=1;
if(x+1<n&&!c[x+1][y]&&!a[x+1][y])
dfs(x+1,y);
if(y+1<3&&!c[x][y+1]&&!a[x][y+1])
dfs(x,y+1);
}
void dfs1(int x,int y)
{
//if(x<0||x>=n||y<0||y>=3||c[x][y]==1&&!b[x][y]) return;
a[x][y]++;
//if(x==0&&y==0) return;
if(x-1>=0&&!c[x-1][y]&&a[x-1][y]==1)
dfs1(x-1,y);
if(y-1>=0&&!c[x][y-1]&&a[x][y-1]==1)
dfs1(x,y-1);
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>k;
for(int i=0;i<n;i++)
{
for(int j=0;j<3;j++)
{
a[i][j]=0;
c[i][j]=0;
}
}
for(int i=0;i<k;i++)
{
cin>>x>>y;
c[x-1][y-1]=!c[x-1][y-1];
}
dfs(0,0);
dfs1(n-1,2);
int s=0;
a[0][0]=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<3;j++)
{
if(a[i][j]==2)
{
s++;
}
//cout<<a[i][j]<<" ";
}
//cout<<endl;
}
cout<<s<<endl;
}
}
3-B-勉强拼凑的记忆
思路:用k个1*k的积木可拼成一个k*k的正方形,此时如果要加宽x的话至少需要x*k+x*k+x*x的面积,a最小为1,即最少要3块积木,所以可加长的长度即为(n-(n+1)/2)/3.
t=int(input())
for i in range(t):
n=int(input())
if (n==2): print(-1)
else:print((n+1)//2+(n-(n+1)//2)//3)
3-C-忽远忽近的距离
思路:构造,当n<=3时无法成立,n=7时也。其余时候,当n%4==0,按照3412规律输出,n%4==1时前面一样,最后5个按34512输出,n%4==2时前面一样,最后6个按356124,n%4==3时最后11个按照3416285101179输出。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int n,k=0;
cin>>n;
if(n<=3||n==7) cout<<-1;
else{
int a[100005];
for(int i=1;i<=n;i++)
{
a[i]=i;
}
if(n%4==0)
{
//cout<<3;
for(int i=1;i<=n;i+=4)
{
if(k==0){
cout<<a[2+i];
k=1;
}
else cout<<" "<<a[i+2];
cout<<" "<<a[3+i]<<" "<<a[i]<<" "<<a[i+1];
}
}
else if(n%4==1)
{
int i=0;
for(i=1;i<=n;i+=4)
{
if(k==0){
cout<<a[2+i];
k=1;
}
else cout<<" "<<a[i+2];
if(i+4==n) break;
cout<<" "<<a[3+i]<<" "<<a[i]<<" "<<a[i+1];
}
cout<<" "<<a[3+i]<<" "<<a[4+i]<<" "<<a[i]<<" "<<a[i+1];
}
else if(n%4==2)
{
int i=0;
for(i=1;i<=n;i+=4)
{
if(k==0){
cout<<a[2+i];
k=1;
}
else cout<<" "<<a[i+2];
if(i+5==n) break;
cout<<" "<<a[3+i]<<" "<<a[i]<<" "<<a[i+1];
}
cout<<" "<<a[4+i]<<" "<<a[5+i]<<" "<<a[i]<<" "<<a[i+1]<<" "<<a[3+i];
/*for(int i=1;i<=n;i++)
{
if(k==0){
cout<<a[i*3];
k=1;
}
else cout<<" "<<a[3*i];
cout<<" "<<a[5*i]<<" "<<a[6*i]<<" "<<a[i*1]<<" "<<a[i*2]<<" "<<a[4*i];
}*/
}
else{
int i=0;
for(i=1;i<=n-11;i+=4)
{
if(k==0){
cout<<a[2+i];
k=1;
}
else cout<<" "<<a[i+2];
//if(i+5==n) break;
cout<<" "<<a[3+i]<<" "<<a[i]<<" "<<a[i+1];
}
cout<<" "<<a[2+i]<<" "<<a[3+i]<<" "<<a[i]<<" "<<a[i+5]<<" "<<a[1+i]<<" "<<a[7+i]<<" "<<a[4+i]<<" "<<a[9+i]<<" "<<a[10+i]<<" "<<a[6+i]<<" "<<a[8+i];
}
}
}
3-E-公平守望的灯塔
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
double x0,x1,y0,y1;
cin>>x0>>y0>>x1>>y1;
double xz=(x0+x1)/2,yz=(y1+y0)/2;
if((abs(int(x1)-int(x0))%2)!=(abs(int(y1)-int(y0))%2)) cout<<"No Answer!"<<endl;
else{
double temp=x0-xz;
xz=y0-yz+xz;
yz=-temp+yz;
cout<<int(xz)<<" "<<int(yz)<<endl;
}
}