前言:
第一场团队赛,和队友没配合好,成绩不太理想。应该几个人开一道的,都管自己想了。想法应该汇总一下,每个人都差一点点…
A
思路:
签到题,队友理解题意理解错了WA了好几发。我一发A了。。。。
1.小于k的增加到它可以增加的最多数量
2.大于等于h的不变
3.最后有一次增加h的机会,总数ans加个k就ok了
AC代码
:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e6+5;
//floor(2.5) = 2
ll a[N];
ll n,k,h;
ll ans=0;
int main()
{
cin>>n>>k>>h;
for(ll i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
for(ll i=1;i<=n;i++)
{
if(a[i]<k)
{
ll t;
if(h!=0) t=(k-a[i])/h;
a[i]=a[i]+h*t;
}
}
for(ll i=1;i<=n;i++)
{
ans+=a[i];
}
ans+=h;
printf("%lld\n",ans);
return 0;
}
H
签到题,按题意模拟即可
队友一A
AC代码:
#include<cstdio>
char zimu;
int map[8][8];
int main()
{
int t;
scanf("%d",&t);
map[1][1]=1;
while(t--)
{
int x=1,y=1;
int n;
scanf("%d",&n);
int i=1;
for(i=2;i<=n*n;i++)
{
scanf(" %c",&zimu);
if(zimu=='s')
x+=1;
if(zimu=='w')
x-=1;
if(zimu=='a')
y-=1;
if(zimu=='d')
y+=1;
map[x][y]=i;
}
for(i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
// if(j!=1)
// printf(" ");
printf("%d ",map[i][j]);
}
printf("\n");
}
printf("\n");
}
}
F
也是签到题
一开始想多了,想找到最优解,一下子找出来。。最后老老实实暴力。。。
思路:
先把每个数从大到小排序,然后和原来的数组比较,如果有一个不一样,说明那两个数就是需要交换的数,然后在原来的数组从后往前找,找到了就退出,然后交换,输出即可。
AC代码
:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1010;
char s[N];
ll a[N];
int t;
int l;
int g[N];
void get()
{
for(int i=1;i<=l;i++)
{
a[i]=s[i]-'0';
g[i]=a[i];
}
}
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
cin>>t;
while(t--)
{
cin>>s+1;
l=strlen(s+1);
get();
int res=-1;
int res2=0x3f3f3f3f;
int maxi=0;
int mini=0;
int last1=0;
int last2=0;
sort(g+1,g+1+l,cmp);
for(int i=1;i<=l;i++)
{
if(a[i]>=res)
{
res=a[i];
maxi=i;
}
}
int flag=1;
for(int i=1;i<=l-1;i++)
{
if(a[i+1]>a[i])
{
flag=-1;
break;
}
}
if(flag==-1)
{
/* for(int i=1;i<=l;i++)
{
printf("%d %d\n",g[i].x,g[i].y);
} */
int flag2=0;
int hh;
for(int i=1;i<=l;i++)
{
if(g[i]!=a[i])
{
for(int j=l;j>=1;j--)
{
if(a[j]==g[i])
{
hh=j;
flag2=-1;
break;
}
}
}
if(flag2==-1)
{
int k=a[i];
a[i]=a[hh];
a[hh]=k;
break;
}
}
}
for(int i=1;i<=l;i++)
{
printf("%d",a[i]);
}
printf("\n");
}
return 0;
}
J
思路:
数据范围很小,模拟即可,要细心。
模拟每一次可以插入的位置,然后一直消到不能消为止。
AC代码
:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,k,x;
int a[200];
cin>>n>>k>>x;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
int maxn=0;
for(int i=0;i<n;i++)
{
int sum=0;
if(a[i]==x)
{
int l=i,r=i,cnt=0;
while(l>=0&&a[l]==x) cnt++,l--;
while(r<n&&a[r]==x) cnt++,r++;
if(cnt>=3)
{
sum=sum+cnt;//去掉的数
while(l>=0&&r<n)
{
int cny=0;
if(l<0||r>=n) break;
int xl=a[l],xr=a[r];
if(xl!=xr) break;
while(l>=0&&a[l]==xr) cny++,l--;
while(r<n&&a[r]==xl) cny++,r++;
if(cny>=3) sum+=cny;
else break;
}
}
}
maxn=max(maxn,sum);
}
if(maxn==0) cout<<0<<endl;
else cout<<maxn-1<<endl;
}
return 0;
}
G
思路:结论题。列几项,找一下规律。
可以发现,要翻倍的时候,翻倍/2的值,是一个等比数列的求和。
然后第一项是k,等比为2。 然后要让它分数最小,就让它翻倍的时候断开,让他错,然后找到最后一个对的翻倍点,加上翻倍点后面对的数量。
小细节:
取余的时候,为了防止出现负数最好 (x+mod)%mod
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mod=1e9+9;
ll n,m,k,a,b,c,ans;
ll qsm(ll b)
{
ll a=2;
ll res=1;
while(b)
{
if(b&1) res=res*a%mod;
b>>= 1;
a=a*a%mod;
}
return res;
}
int main()
{
while (scanf ("%lld%lld%lld", &n, &m, &k) != EOF)
{
b=n/k;//有几个断点
a=n-m; //需要错几个点。
ans=0;
if(m<k) ans=m;
else if(a>=b) ans=m;
else
{
c=b-a;
ans = (k*((qsm(c+1) + mod - 2)%mod) %mod + m - c*k) % mod;
}
printf("%lld\n",ans);
}
return 0;
}
E
思路:
当时是想用两个变量记录,标记过的区间的左端点和右端点,但是想了一下如果新的区间和原来区间没有交集就不知道怎么办了。
这里他开了个 一维数组,把区间内所有点都赋值为右端点的下标,很巧妙。学到了
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6;
int g[N];
int d[N];
int n,m,a,b;
int main()
{
cin>>n>>m>>a>>b;
for(int i=m;i>=1;i--)
{
int x=(i*a+b)%n+1;
int y=(i*b+a)%n+1;
if(x>y) swap(x,y);
for(int j=x;j<=y;j++)
{
if(!d[j])
{
d[j]=y;
g[j]=i;
}
else
{
j=d[j];
}
}
}
for(int i=1;i<=n;i++)
{
cout<<g[i]<<endl;
}
return 0;
}
I
思路:
如果第一个行的a[1][i]是1,那么a[1,i] a[1,i-1] a[1,i+1]都不能为1,
然后用一个cnt记录,不能走的个数。
当每次发生变化的时候 更新这个cnt ,最后根据cnt是否为0判断能否到达。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int cnt;
int mp[4][N];
int n;
void print()
{
if(cnt) cout<<"You are the worst friend.\n";
else cout<<"I'm the worst friend.Please forgive me.\n";
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=2;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&mp[i][j]);
}
}
for(int i=1;i<=n;i++)
{
if(mp[1][i]==1)
{
if(mp[2][i]) cnt++;
if(mp[2][i+1]) cnt++;
if(mp[2][i-1]) cnt++;
}
}
print();
int m;
scanf("%d",&m);
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
mp[a][b]^=1;
if(mp[a][b])
{
if(mp[a+1][b-1]) cnt++;
if(mp[a+1][b]) cnt++;
if(mp[a+1][b+1]) cnt++;
if(mp[a-1][b-1]) cnt++;
if(mp[a-1][b]) cnt++;
if(mp[a-1][b+1]) cnt++;
}
else
{
if(mp[a+1][b-1]) cnt--;
if(mp[a+1][b]) cnt--;
if(mp[a+1][b+1]) cnt--;
if(mp[a-1][b-1]) cnt--;
if(mp[a-1][b]) cnt--;
if(mp[a-1][b+1]) cnt--;
}
print();
}
return 0;
}