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