啊~,对于这套题我最想说的是我H居然没过,看来当时真的是比较累(虽然没做多长时间就去吃饭了-_-!!),赛后睡一觉再看题不到20分钟AC了,脑窝疼T_T。
晚上补题不顺,B是矩阵快速幂明天在更新。
题意:给你n个木棍问最多能组成多少个三角形,木棍最多只能组一个三角形。
思路:排序,从小到大遍历三条边三个循环,注意判断木棍使用就行。
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define INF 0x3f3f3f3f
LL a[20];
int f[20];
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lld",&a[i]);
}
sort(a,a+n);
int sum=0;
memset(f,0,sizeof(f));
for(int i=0;i<n;i++)
{
if(f[i]==0){
for(int j=i+1;j<n;j++)
{
if(f[j]==0){
if(f[i]) break;
for(int k=j+1;k<n;k++)
{
if(f[k]==0){
if(f[j]) break;
if(f[i]) break;
if(a[i]+a[j]>a[k])
{
sum++;
f[i]=1;f[j]=1;f[k]=1;break;
}
}
}
}
}
}
}
printf("%d\n",sum);
}
Gym 100735E
题意:给你一个去掉一条正对角线的矩阵让你还原成所有行所有列的和都相等。
思路:分析分析题意后会发现有规律可寻,可假设左上角的值为x,那么接下来对角线上所有的的值都可以得到关于x的表达式,最后直接解方程就行啦。
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define INF 0x3f3f3f3f
LL a[105][105],b[105];
int main()
{
int n;
scanf("%d",&n);
memset(b,0,sizeof(b));
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
scanf("%lld",&a[i][j]);
b[i]+=(a[i][j]);
}
}
LL sum=0;
for(int i=1;i<n;i++)
{
sum+=b[0]-b[i];
}
a[0][0]=(b[0]-sum)/(n-1);
for(int i=1;i<n;i++)
{
a[i][i]=a[0][0]+(b[0]-b[i]);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(j!=n-1)
printf("%lld ",a[i][j]);
else
printf("%lld",a[i][j]);
}
printf("\n");
}
}
Gym 100735G
题意:给你一个由0和1组成的序列A然后求长度和A序列一样的最小最长公共子序列。
思路:简单的思考题,由于都只有0和1那么就是求A中0和1哪个数量最少。
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define INF 0x3f3f3f3f
char str[100005];
int main()
{
scanf("%s",str);
int len=strlen(str);
int sum=0;
for(int i=0;i<len;i++)
{
if(str[i]=='0') sum++;
}
int ans=len-sum;
printf("%d\n",min(ans,sum));
}
题意:给你一个字符串S和n个六面的小方块,小方块每个面有个数字或者小写英文字母,问能否用这n个方块中的某些或者全部构成S。
思路:深搜遍历,以S第一个字母开始。
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define INF 0x3f3f3f3f
char str[105],str1[105][10];
int vis[105];
struct Node
{
int x,y;
}d[1005];
int ans=0,n,len=0;
void dfs()
{
if(ans==len) return;
for(int i=0;i<n;i++)
{
if(vis[i]) continue;
for(int j=0;j<6;j++)
{
if(str1[i][j]==str[ans])
{
ans++;vis[i]=1;
if(len==ans) return;
dfs();
if(len==ans) return;
ans--;vis[i]=0;break;
}
}
}
}
int main()
{
cin>>str>>n;
int sum=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<6;j++)
{
cin>>str1[i][j];
if(str1[i][j]==str[0])
{
d[sum].x=i;d[sum++].y=j;
}
}
}
len=strlen(str);
memset(vis,0,sizeof(vis));
for(int i=0;i<sum;i++)
{
vis[d[i].x]=1;
ans=1;
dfs();
if(ans==len)
{
printf("YES\n");return 0;
}
ans=0;
vis[d[i].x]=0;
}
printf("NO\n");
}
题意:给你A,B,C三个数问能否用这三个数的某些数得到a+b=c;
思路:由于数据比较大,我只能套用java来做。如果用c++还得自己写个类,比较麻烦建议用java
代码如下:
import java.io.*;
import java.math.*;
import java.util.*;
import java.text.*;
public class p
{
public static void main(String[] args)
{
Scanner cin=new Scanner (System.in);
BigInteger a=new BigInteger(cin.next());
BigInteger b=new BigInteger(cin.next());
BigInteger c=new BigInteger(cin.next());
if(a.add(a).equals(b)||a.add(a).equals(c)||a.add(b).equals(c)
||b.add(b).equals(a)||b.add(b).equals(c)
||b.add(c).equals(a)||c.add(c).equals(a)||
c.add(c).equals(b)||c.add(a).equals(b))
{
System.out.println("YES");
}
else System.out.println("NO");
}
}