A题:给你n个数,问你有多少数<=n个数和/n.
方法:求个和,跑一边判断每个数*n是不是小于等于和。
B题:给你n*m的一个纸,然后模拟2种操作,一种是从左往右折叠,一种是从下往上折叠,然后p次询问,在某点打孔能打透多少纸,直接模拟下过程即可。
int geta(int i,int j)
{
if(i<0||i>=n||j<0||j>=m)return 0;
return a[i][j];
}
int main()
{
while(scanf("%d%d%d%d",&n,&m,&t,&p),n)
{
memset(a,0,sizeof(a));
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
a[i][j]=1;
while(t--)
{
scanf("%d%d",&x,&y); //1 lr 2du
if(x==1)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
b[i][j]=geta(y+i,j)+geta(y-1-i,j);
}
}
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
a[i][j]=b[i][j];
}
else
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
b[i][j]=geta(i,y+j)+geta(i,y-1-j);
}
}
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
a[i][j]=b[i][j];
}
}
while(p--)
{
scanf("%d%d",&x,&y);
printf("%d\n",a[x][y]);
}
}
return 0;
}
C题
题意:给你一个数,问你让最多的连续的数的和等于它,然后问你起始点在哪里,长度是多少。
思想:直接枚举肯定GG,化简等差数列求和公式即可,然后考虑枚举的最多不会超过sqrt(2*n),暴力枚举长度,公式计算起始点,最大的那个直接输出。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ll n;
while(scanf("%lld",&n)!=EOF)
{
if(n==0)
break;
ll len=(sqrt(2*n));
ll ans;
for(;len>=1;len--)
{
ll x=(2*n-len*len+len)/2/len;
if(len*(x+x+len-1)/2==n)
{
ans=x;
break;
}
}
printf("%lld %lld\n",ans,len);
}
return 0;
}
D题:
给你奇数个球队,想要形成一种局面,就是每个球队胜利和失败的次数一样多,问你有多少种不同的结果。
看到n不大直接想到dfs,每个队伍的赢不会超过(n-1)/2,这样来判断T到怀疑人生,然后看了看别人的,发现自己傻了,直接搜索的时候一个三角形即可,然后在用两个队伍的lose次数和win次数来限制,这样搜索的更少了。
从(1,2)或者(n,1)搜都比较好写判断,下面给(1,2) (n,1)自己写下。
#include<bits/stdc++.h>
using namespace std;
int win[10];//标记胜利的次数
int los[10];
int vis[10][10];//标记胜利
long long ans;
int n,m,temp;
void dfs(int x,int y)
{
if(y==n+1)//换行
{
x++;
y=x+1;
}
if(x==n)//到达终点
{
ans++;
return ;
}
if(vis[x][y]==1)
dfs(x,y+1);
else//是一个不确定的点
{
//printf("%d %d %d %d %d\n",x,win[x],y,los[y],temp);
if(win[x]<temp && los[y]<temp)
{
win[x]++;
los[y]++;
dfs(x,y+1);
win[x]--;
los[y]--;
}
if(win[y]<temp && los[x]<temp)
{
win[y]++;
los[x]++;
dfs(x,y+1);
win[y]--;
los[x]--;
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
memset(vis,0,sizeof(vis));
memset(win,0,sizeof(win));
memset(los,0,sizeof(los));
scanf("%d",&m);
int flag=1;
temp=(n-1)/2;
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
win[a]++;
los[b]++;
vis[a][b]=1;//标记打过了
vis[b][a]=1;
if(win[a]>(n-1)/2 || los[b]>(n-1)/2)
flag=0;
}
if(flag==0)
{
printf("0\n");
continue;
}
ans=0;
dfs(1,2);
printf("%lld\n",ans);
}
return 0;
}
E题:
E题不多解释了,队友赛后搞掉的,问了队友,然后沉思很久,然后噼里啪啦,然后过了示例,然后WA,然后看了看代码,嗯,写错了,一顿噼里啪啦,过了。
贴下队友博客:https://blog.csdn.net/winter2121/article/details/81986176