传送门:杭电6511-6521
目录
HDU6511 Min-Max
HDU6512 Triangle
HDU6513 Reverse it
HDU6514 Monitor
HDU6515 Coding problem
HDU6516 Network
HDU6517 Bring Bring big teacher brother
HDU6518 Clumsy Keke
HDU6519 Enlarge it
HDU6520 Silly Keke
HDU6521 Party
题意:有一个长度为n的随机排列以及m个min、max操作。问最后一个操作的结果的期望 * n! 的结果。
思路:把一组数组按大于等于k与否用1\0表示,再按操作来一遍,如果结果为1,说明可行。而如果这个01数组有x个1,那么它对应的正常数组有x!*(n-x)!个。
#include
#include
#include
#define ll long long
using namespace std;
bool a[1<<16][16];
ll fac[16];
bool b[1001];
int n,m;
struct op{
bool oper,flagx,flagy;//oper表示是否max,flag表示是否数组a、b,
int x,y;
}op[1001];
void pre()
{
memset(a,0,sizeof(a));
int x=1<>=1)
a[i][j]=t&1;
}
void getfac()
{
fac[0]=1;
for(int i=1;i<=15;i++)
{
fac[i]=fac[i-1]*(ll)i;
}
}
bool Find(int i) //对a[i]数组做模拟运算
{
for(int j=1;j<=m;j++)
{
if(op[j].oper)
{
if(op[j].flagx&&op[j].flagy) b[j]=max(a[i][op[j].x],a[i][op[j].y]);
else if(op[j].flagx&&!op[j].flagy) b[j]=max(a[i][op[j].x],b[op[j].y]);
else if(!op[j].flagx&&!op[j].flagy) b[j]=max(b[op[j].x],b[op[j].y]);
else b[j]=max(b[op[j].x],a[i][op[j].y]);
}
else
{
if(op[j].flagx&&op[j].flagy) b[j]=min(a[i][op[j].x],a[i][op[j].y]);
else if(op[j].flagx&&!op[j].flagy) b[j]=min(a[i][op[j].x],b[op[j].y]);
else if(!op[j].flagx&&!op[j].flagy) b[j]=min(b[op[j].x],b[op[j].y]);
else b[j]=min(b[op[j].x],a[i][op[j].y]);
}
}
return b[m];
}
int getnum(int i)
{
int ans=0;
for(int j=1;j<=n;j++)
if(a[i][j]) ans++;
return ans;
}
int main()
{
string str;
char x,y;
int p,q;
getfac();
while(scanf("%d%d",&n,&m)!=EOF)
{
pre();
ll ans=0;
for(int i=1;i<=m;i++)
{
cin>>str>>x>>p>>y>>q;
if(str=="max") op[i].oper=1;
else op[i].oper=0;
if(x=='a') op[i].flagx=1;
else op[i].flagx=0;
if(y=='a') op[i].flagy=1;
else op[i].flagy=0;
op[i].x=p;op[i].y=q;
}
for(int i=0;i<(1<
题意:给你n根棍子,问你是否有其中三根可以组成三角形。
思路:不能组成三角形的数至少构成斐波那契数列。故我们可以算出2的32次方对应第x个斐波那契数,那么当输入n>x时,必然输出YES,否则进行排序,判断是否有a[i]+a[i+1]>a[i+2]。
//第50个斐波那契数已经超过int的限度了。
//如果用三次循环和break也能通过。
#include
#include
#include
#include
#define ll long long
using namespace std;
int main()
{
int n;
int a[5000005];
while(cin>>n)
{
for(int i=0;i50) cout<<"YES"<a[i+2])
{
flag=1;
break;
}
if(flag) cout<<"YES"<
题意:有一个n行m列的卡牌阵,每个位置是0或1,0代表卡牌背面朝上,1代表卡牌正面朝下。每次可以选择一个小矩阵,把这个矩阵内所有卡牌翻转,问最后可以得到多少本质不同的卡牌阵。
题意:在一个面积不超过n*m的矩形上,有p个矩形A,问之后的q个矩形B能否被之前的A全部覆盖。
思路:数据范围超大,用到了二维前缀和,所谓二维前缀和既是v[i,j]表示从(0,0)到(i,j)的面积。
#include
#include
#include
#include
#include
#define ll long long
#define MAX 10000007
using namespace std;
int v[MAX];
int m,n;
void add(int i,int j,int k)
{
if(i>m||j>n) return;
v[(i-1)*n+j]+=k;
}
int query(int i,int j)
{
if(i==0||j==0) return 0;
return v[(i-1)*n+j];
}
void Print()
{
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++) cout<>m>>n)
{
memset(v,0,sizeof(v));
cin>>k;
while(k--)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
add(x1,y1,1);
add(x2+1,y2+1,1);
add(x1,y2+1,-1);
add(x2+1,y1,-1);
}
//二维前缀和
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
v[(i-1)*n+j]+=query(i-1,j)+query(i,j-1)-query(i-1,j-1);
//Print();//确定某一点有无被覆盖
for(int i=1; i<=n*m; i++)
if(v[i]) v[i]=1;
//再求前缀和
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
v[(i-1)*n+j]+=query(i-1,j)+query(i,j-1)-query(i-1,j-1);
cin>>k;
while(k--)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
int tmp=query(x2,y2)+query(x1-1,y1-1)-query(x1-1,y2)-query(x2,y1-1);
if(tmp==((x2-x1+1)*(y2-y1+1))) cout<<"YES"<
题意:将字符串每个字符ASCII的二进制翻转码组成的字符串以每6个一组输出。
思路:模拟
#include
#include
#include
#include
#include
#define ll long long
#define p (i*8+j)/6
using namespace std;
int main()
{
string a;
int ans[400004];
while(cin>>a)
{
memset(ans,0,sizeof(ans));
int n=a.length();
for(int i=0;i>=1)
ans[p]=(ans[p]<<1)+(a[i]&1);
for(int i=0;i<(n/3*4);i++)
cout<
题意:给定一个立方堆的三视图,求它的体积(有多种可能则输出最大)。
思路:如果下面的代码不好理解的话,可以考一下切割,即建立一个v[100][100][100],初始为1,慢慢切割,最后统计。
#include
#include
#include
#include
#include
#define ll long long
#define p (i*8+j)/6
using namespace std;
int main()
{
int x,y,z;
while(cin>>x>>y>>z)
{
int ans=0;
bool f[100][100],t[100][100],s[100][100];
for(int i=0;i>f[i][j];
for(int i=0;i>t[i][j];
for(int i=0;i>s[i][j];
for(int i=0;i
题意:输入一个字符矩阵,把它放大k倍输出。
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
int main()
{
int m,n,k;
char a[100][100],b[1000][1000];
while(cin>>m>>n>>k)
{
for(int i=0;i>a[i][j];
for(int i=0;i
题意:有n个人,开m次派对,每次派对每对人会相互认识对方。对于每一次派对,我们要求出新认识的pair的数量。