c语言ACM趣味编程100例,电子科技大学第九届ACM趣味程序设计竞赛第二场(正式赛) 题解...

A::魔王的直播

注意23:59之后是00:00即可,找出所有回文字符,取最近.

#include

using namespace std;

bool check(int a,int b)

{

int c=a%10*10+a/10;

if(c==b)

return false;

return true;

}

int main()

{

int a,b;

scanf("%d:%d",&a,&b);

int ans=0;

while(check(a,b))

{

ans++;

b++;

a+=b/60;

b%=60;

a%=24;

}

cout<

}

B:绿帽自动机

题意:

定义“戴绿帽”操作:除了制定某一个某一个人之外,其他人的绿帽数+1。

给定n个数,进行尽量少的“戴绿帽”操作,使得第x个数最大。

输出“戴绿帽”操作所需的最少次数。

首先,明确一点,如果我一次性给所有人“戴绿帽”,那么“戴绿帽”前后,最大的那个人的绿帽数依旧最大,最小的那个依旧最小,即不影响题目要求。

现在题意为“ 除了指定的某一个人以外,其余所有人绿帽数+1”,可以分解为以下操作:

1.给所有人绿帽数+1

2.给指定的那个人绿帽数-1

事实上,题目就等价于:每次减少一个人的绿帽,至少进行多少次减少操作,可以使得第x-th数最大。

假设第x人原绿帽数为g,那么计算一下所有大于等于g-1的数与g-1的差即可。

结果可能爆int,请使用long long。

#include

using namespace std;

typedef long long ll;

const int MAXN = 100000+10;

ll g[MAXN];

ll sum;

int main()

{

int n,x;

cin>>n>>x;

for(int i=1;i<=n;++i)cin>>g[i];

for(int i=1;i<=n;++i)if(g[i]>=g[x]-1)sum+=(g[i]-g[x]+1);

cout<

return 0;

}

C:洗牌机

洗牌方式是一个大环,因此连续洗牌 13 次后所有牌又会回到原位,那么洗一次牌相当于洗7*2次牌。

我们只需要模拟洗7*2次即可。

根据初始顺序和洗两次后的顺序,得到洗两次的洗牌方式,用二重循环,外循环模拟每一次洗牌,内循环模拟洗每一张牌,再输出洗7*2次牌后的结果。

#include

using namespace std;

#define N 15

int a[N][N],nxt2[N],num;

//a[i][j]��ʾϴi���ƺ�ĵ�j����

//nxt2[i]=j��ʾԭ����i������ϴ���κ��ܵ���j��

int main()

{

int n=13,times=7;

scanf("%d",&num);

while(num--)

{

for(int i=1; i<=n; i++)

scanf("%d",&a[0][i]);

for(int i=1; i<=n; i++)

scanf("%d",&a[2][i]);

for(int i=1; i<=n; i++)

for(int j=1; j<=n; j++)

if(a[0][i]==a[2][j])

{

nxt2[i]=j;

break;

}

for(int t=1; t

for(int i=1; i<=n; i++)

{

a[2*(t+1)][nxt2[i]]=a[2*t][i];

}

for(int i=1; i<=n; i++)

{

printf("%d ",a[14][i]);

}

printf("\n");

}

return 0;

}

D:小帆宝与数字8

题目要求你得到一个长度为n的排列,使得相邻两个数的乘积都是8的倍数

1 2 4 8,这四个数,可以知道,1和1不能在一起,1和2不能在一起,1和4不能再一起,2和2不能在一起,其他都可以在相邻

并且1只能和8在一起,所以要让1旁边有尽量少的空位,那么我们就从第一个位置开始放1,并且隔一个位置,再放下一个1,直到把1放完,这样使得1旁边

有最少的空位。

如果这样放到最后要给位置,还没有把1放完,那么就是无解,输出NO

对于2,只要和2不相邻且和1不相邻。所以接着之前放1的位置的下下个位置放2,直到把2放完,这样可以放置最多的2。

如果这样放到最后一个位置,还没有把2放完,那么就是无解,输出NO

然后在空着的位置,先放8,再放4

最后check一下,相邻的乘积是否为8的倍数

如果不是,输出NO

如果是,输出YES

举个例子

6

1  1  2  4  8  8

先放置1,即第一个和第三个位置为1

再放置2,即第五个位置为2

然后先放8,即第二和第四个位置是8

最后放置4,即第六个位置是4

1 8 1 8 2 4  答案即是这个。

#include

#include

using namespace std;

int a[4];

int b[105];

int main()

{

int n;

scanf("%d",&n);

for(int i=0;i

{

int x;

scanf("%d",&x);

if(x==1) a[0]++;

if(x==2) a[1]++;

if(x==4) a[2]++;

if(x==8) a[3]++;

}

int flag=0;

for(int i=0;i

{

if(a[flag]==0)

{

if(flag==0) flag++;

if(a[flag]==0) break;

}

b[i]=flag+1;

a[flag]--;

}

if(a[0]!=0||a[1]!=0)

{

printf("NO\n");

return 0;

}

flag=3;

for(int i=0;i

{

if(b[i]!=0) continue;

if(a[flag]==0)

{

if(flag==3) flag--;

}

if(flag==3) b[i]=8;

else b[i]=4;

a[flag]--;

}

bool sign=0;

for(int i=1;i

{

if(b[i]*b[i-1]%8!=0)

{

printf("NO\n");

sign=1;

}

}

if(sign==0)

{

printf("YES\n");

for(int i=0;i

}

return 0;

}

E:矩阵

当K=1时

先随便写出一个(N-1)*(M-1)的元素为1或-1的矩阵

对第i(1<=i<=N-1)行进行分类讨论

如果第i行里第1列到M-1列的元素之积为1,则在第N行第M列里填充1,则显然会使得第i行从第1列到第M列的元素之积为1,

如果第i行里第1列到M-1列的元素之积为-1,则在第N行第M列里填充-1,则显然会使得第i行从第1列到第M列的元素之积也为1,

也就是说令

对第j(1<=J<=M-1)列也这样处理,即令

这样分别处理完以后就可以保证第1行到第N-1行的各行内元素之积一定为1且第1行到第N-1列的各列内元素之积也一定为1,那么只要使得第N行和第M列的元素之积为1就可以了。

因为矩阵A的元素 ,

那么可以得到和,容易得到,也就是说不论在第N行第M列里填充1或者-1,都会使得第N行和第M列内各元素之积相等,所以,只要令就可以使得这个矩阵满足条件了。而且,显然可以的知道不论一个什么样的(N-1)*(M-1)的矩阵都有且只有一个满足K=1的条件的N*M的矩阵与之对应,也就是说当K=1时,答案就是

当K=-1的时候,方法与k=1的时候类似,但是当N和M的奇偶性不一样的时候就会使得不论一个什么样的(N-1)*(M-1)的矩阵都不会存在一个与之对应的符合条件的N*M的矩阵。因为此时 ,而

不论在第N行第M列里填充1或者-1,都会使得第N行和第M列内各元素之积都不 相等。

所以当K=-1且N,M的奇偶性相同时,答案就是,否则是0。

#include

#include

#include

#define ll long long

using namespace std;

int n , m , k;

int main(){

scanf("%d%d%d",&n,&m,&k);

if ( ( k == 1) || ( ( k==-1 ) && ( (n+m)%2== 0 ) ) )

{

long long ans=1;

for (int i = 1;i<= n-1 ;i++)

for (int j= 1; j<=m-1;j++)

ans=ans*2ll;

cout<

}

else

puts("0");

return 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值