列表

详情


NC21478. 白井黑子

描述

kuroko 作为常盘台唯一的空间系能力者,在每年例行的能力测试中可绝对不能让 misaka 失望哦,但是由于她的等级只是 level 4「大能力者」,在能力测试中会遇到不少困难。kuroko 是一个凡事都会尽力的好女孩,所以请你帮她算出她最多能完成多少测试吧

对于空间系能力者测试的内容是检验对物体进行空间移动的能力,测验时一共有 n 个物品放在一条直线上,每个物品都有一个坐标 ai ,kuroko 可以选择两个物品并使用能力交换它们的位置,但是如果两个物品的坐标不满足 kuroko 的计算公式的话,她就没有办法使用能力。

具体来说,对于坐标 ai ,其在 kuroko 的计算公式中是用参数 f(ai) 表示的。f(ai) 是 ai 各数位相乘的结果,由于 level 4「大能力者」在学园都市中也是很强大的存在,所以满足公式的条件不会太苛刻,对于两个物品 ai, aj ,如果 f(ai) x f(aj) 不能被某个自然数的 k 次幂表示 的话,那么 kuroko 就能对这两个物品使用能力。

现在 kuroko 想知道,有多少对物品她可以对其施展能力,知道了这个后她就知道自己能完成多少测验了。

这里认为任何自然数的 0 次幂都是 1。

输入描述

第一行两个数,n, k 。

第二行共 n 个数 ai 表示这 n 个物品在直线上的坐标。

输出描述

输出共一个数,表示 kuroko 能对其使用能力的无序物品对数。

示例1

输入:

6 3
113 10 11 1110 33 110

输出:

2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 199ms, 内存消耗: 2736K, 提交时间: 2019-10-23 21:28:41

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll f(ll x){
    ll sum = 1;
    while(x){
        sum = sum*(x%10);
        x /= 10;
    }
    return sum;
}
map<vector<ll> , ll> mp;
vector<ll> b(4),v(4);
int a[4] = {2,3,5,7};
int main()
{
    ll n,k;
    cin >> n >> k;
    if(k == 0){
        ll flag = 0;
        for(int i = 0; i < n; i ++){
            ll x;
            cin >> x;
            ll y = f(x);
            if(y == 1) flag ++;
        }
        
        cout << n*(n - 1)/2 - flag*(flag-1)/2 << endl;
    }
    else{
        ll flag = 0;
        ll cnt = 0;
        for(int i = 0; i < n; i ++){
            ll x;
            cin >> x;
            ll y = f(x);
            if(y){
                for(int j = 0; j < 4 ; j ++){
                    v[j] = 0;
                    while(y%a[j] == 0){
                        y /= a[j];
                        v[j] ++;
                    }
                    v[j] %= k;
                    b[j] = (k - v[j])%k;
                }
                cnt += mp[b];
                mp[v] ++;
            }
            else flag ++;
        }
        if(flag)
        cnt = flag*(flag - 1)/2 + cnt + flag*(n - flag);
        cnt = n*(n - 1)/2 - cnt;
        cout << cnt << endl;
    }
}

C++11(clang++ 3.9) 解法, 执行用时: 95ms, 内存消耗: 1888K, 提交时间: 2018-11-23 23:16:27

#include<bits/stdc++.h>
using namespace std;
using LL=long long;
const LL mos[4]={2,3,5,7};
map<vector<LL>,LL>my;

int main()
{
	LL n,k;
	scanf("%lld%lld",&n,&k);
	vector<LL>s1;
	vector<LL>s2;
	s1.resize(4),s2.resize(4);
	int i,j;
	LL t;
	LL cnt=0;
	LL ans=0;
	for(i=0;i<n;i++)
	{
		scanf("%lld",&t);
		LL now=1;
		while(t)
		{
			now*=t%10;
			t/=10;
		}
		if(k==0)
		{
			if(now==1)
				cnt++;
			continue;
		}
		if(now==0)
		{
			cnt++;
			continue;
		}
		for(j=0;j<4;j++)
		{
			int num=0;
			while(now%mos[j]==0)
			{
				now/=mos[j];
				num++;
			}
			num%=k;
			s1[j]=num;
			s2[j]=(k-num)%k;
		}
		ans+=my[s2];
		my[s1]++;
	}	
	if(k==0){
		ans=n*(n-1)/2-cnt*(cnt-1)/2;
	}
	else
	{
		ans=ans+cnt*(n-cnt)+(cnt-1)*cnt/2;
		ans=n*(n-1)/2-ans;
	}
	printf("%lld\n",ans);
	return 0;
} 

上一题