2019-2020 ICPC Asia Taipei-Hsinchu Regional Contest(C,D,H,J,K)

前言:

萌新的第一次尝试写写icpc题,就上cf Gym里找了一套4星难度的题(满星是5星),因为自己一直刷视频学算法感觉到无聊,所以自己决定修正下自己学习算法的方法,改为刷题遇见后去学习,这样能很好的刺激自己主动性。所以每一套icpc的题我自己都要求写完每一道题,尽量ak,除非真的没有题解,一点提示都没有,再加上自己毫无想法。

2020/11/2更新 C D H K

2020/11/4更新J

关于第一次写icpc:

个人认为台北这套题非常适合当萌新的第一套icpc题,个人就只写了签到,剩下的会慢慢更新,本场签到题极其温和,但是剩下的没看,但是cf上4星说明还是非常有难度,所以后面的题会陆续更新题解。

题目链接:

http://codeforces.com/gym/102460

2020/11/2更新

Problem C Are They All Integers?
标签:暴力
题意:
就是给你1 ~ n个正整数(正整数范围1 ~ 100),问有没有随机的3个数(不能重复选择一样的数)使(a[i]-a[j])/a[k]等于正整数一直满足。
i,k,j是1 ~ n的下标。a[i],a[k],a[j]是下标对应的数字.
思路:
n是50,直接暴力就行了,注意一点就是别选选过的数字就行了。
代码:

#include
using namespace std;
const int N=100;
int a[N],b[N];
int t;
int main()
{
    scanf("%d",&t);
    for(int i=1;i<=t;i++)
    {
        scanf("%d",&a[i]);
        b[i]=a[i];
    }
    int flag=0;
    for(int i=1;i<=t;i++)
    {
        for(int j=1;j<=t;j++)
        {
            if(j==i) continue;
            b[j]-=a[i];
        }
        /*for(int j=1;j<=t;j++) cout<
        for(int j=1;j<=t;j++)
        {
            if(j==i) continue;
            for(int n=1;n<=t;n++)
            {
                if(n==i||n==j) continue;
                if(b[j]==0||a[n]==1||(b[j]%a[n]==0)) continue;
                else flag=1;//cout<
            }
        }
        for(int i=1;i<=t;i++) b[i]=a[i];
    }
    if(flag) puts("no");
    else puts("yes");
    return 0;
}

Problem D Tapioka
标签:字符串
题意:
让你从3个字符串里删除他题中2种字符串,如果全部删除就输出nothing。
思路:
就搜一遍就完了,直接输出。
代码:

#include 
#include 
#include 
 
using namespace std;
 
string a, b, c;
 
int main(){
    cin >> a >> b >> c;
     
    int cnt = 0;
    if (a != "bubble" && a != "tapioka") cout << a << ' ', cnt ++;
    if (b != "bubble" && b != "tapioka") cout << b << ' ', cnt ++;
    if (c != "bubble" && c != "tapioka") cout << c << endl, cnt ++;
    if (cnt == 0) puts("nothing");
    return 0;
}

Problem H Mining a
标签:二进制
题意:
给你一个公式
1/n=1/(a(xor)b)+1/b;
只给你n的值要求输出a的最大值
思路;
1/n=1/(a(xor)b)+1/b公式变形1/n-1/b=1/(a(xor)b)
然后我猜想b=n+1,公式就变成
(n^2+n)=(n+1)(xor)a;
直接求a就行了
代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
ll t,x;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
    //freopen("test.in","r",stdin);
    //freopen("test.out","w",stdout);
	cin>>t;
	while(t--)
	{
		cin>>x;
		ll num=(x*(x+1))^(x+1);
		cout<<num<<endl;
	}
	return 0;
}

Problem K Length of Bundle Rope
标签:小根堆
题意:
给你n个包裹需要绳子的长度,只能两个两个的绑在一起,求最少需要多长的绳子?
样例解释: 5 8 14 26
5+8=13;
13+14=27;
26+27=53;
所以最小值是13+27+53=93
思路:维护小根堆每次拿两个,然后相加放回去,每次把相加的值累加即可。
代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
int t,n;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
    //freopen("test.in","r",stdin);
    //freopen("test.out","w",stdout);
	cin>>t;
	while(t--)
	{
		cin>>n;
		priority_queue<int,vector<int>,greater<int> > q;
		for(int i=1;i<=n;i++)
		{
			int x;
			cin>>x;
			q.push(x);
		}
		int sum=0;
		while(q.size()>1)
		{
			int num1=q.top();
			q.pop();
			int num2=q.top();
			q.pop();
			sum+=(num1+num2);
			q.push(num1+num2);
		}
		q.pop();
		cout<<sum<<endl;
	}
	return 0;
}

2020/11/4更新

**Problem J Automatic Control Machine **
标签:暴力,深搜,bitset
题意:
给你许m多个长度为n字符串,每个字符串都是由0和1构成,求最少选取多少个使的字符串每一位都变成1需要几个字符串。相当于or的操作。
思路:
纯暴力,只是会用到一个结构bitset进行储存数据和与运算。
我们来做个笔记关于bitset,可能大家原来都没用过。

bitset:

C++的 bitset 在 bitset 头文件中,它是一种类似数组的结构,它的每一个元素只能是0或1,每个元素仅用1bit空间。
bitset数组与vector数组区别
bitset声明数组:bitset<100> number[10]
vector声明数组:vector number[10];
bitset<每个bitset元素的长度(没有占满前面全部自动补0)> 元素
bitset内置转化函数:可将bitset转化为string,unsigned long,unsigned long long。
代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
int t,n,m;
char str[1010];
bitset<500> number[30];
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
    //freopen("test.in","r",stdin);
    //freopen("test.out","w",stdout);
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d %d",&n,&m);
		for(int i=0;i<m;i++)
		{
			scanf("%s",str);
			number[i]=bitset<500>(str);
		}
		int len=1<<m,ans=m+1;
		for(int i=1;i<len;i++)
		{
			int t=i,s=0;
			bitset<500> num(0);
			for(int j=0;j<m&&t>0;j++)
			{
				if(t&1) 
				{
					num=num|number[j];
					s++;
				}
				t>>=1;
			}
			if(num.count()==n) ans=min(ans,s);
		}
		if(ans==m+1) printf("-1\n");
		else printf("%d\n",ans);
	}
	return 0;
}

此题还可以深搜大佬们可以写写看康康

//
后续题目会继续更新周期大概在1~2天左右

你可能感兴趣的:(算法)