A题:IQ test,23333。就是给你n个数,求出一个跟其他数不一样的数的下标。
很明显,不同是根据奇偶区分。然后就容易了。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
int a[105];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int x,y;
x=0,y=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(a[i]%2==0)
x++;
else
y++;
}
if(x > y)
{
for(int i=0;i<n;i++)
{
if(a[i]%2!=0)
printf("%d\n",i+1);
}
}else{
for(int i=0;i<n;i++)
{
if(a[i]%2==0)
printf("%d\n",i+1);
}
}
}
return 0;
}
B题:给你一串数字。代表着电话号码,问你能不能分解成2个或者3个一组的,用“-”区分。
第一下看到的题感觉是处理字符串,再想想构造方案的时候,以为是数论。就是把100以内的数学分解为2 3 这两个数组相加的和,然后再想想其实没有不存在的情况。
如果n为偶数,那么我全部分为2个一组的。如果为奇数,我就分为(n-1)/2-1组2个的,然后把剩下的两个和多出来的一个构造为第三个。这样就可以了。
题目很水,但是很有启发性,我如果把范围加大,然后把2和3这两个数字改一下。大家可以思考一下?
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
char a[105];
int main()
{
int n;
while(cin>>n)
{
cin>>a;
if(n%2 == 0)
{
for(int i=0;i<n;i++)
{
cout<<a[i];
if(i%2 == 1&&i != n-1)
cout<<"-";
}
printf("\n");
}else{
for(int i=0;i<n-3;i++)
{
cout<<a[i];
if(i%2 == 1)
cout<<"-";
}
cout<<a[n-3]<<a[n-2]<<a[n-1];
printf("\n");
}
}
return 0;
}
C题:给一个数,如果它能分解为2个素数乘积。注意18=2*2*3 这种也算只有2个。
然后我居然发现这个跟上面题有点异曲同工的感觉,上一题是和,这道题是乘积。就无脑枚举就可以了吧,也可以打个3000以内的素数表搞,我是边枚举一个数,边更新n的。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
bool check(int x) {
int num = 0;
for (int i = 2; i * i <= x; ++i) {
if (x % i == 0) {
++num;
while (x % i == 0)
x /= i;
if (x == 0)
break;
}
}
if (x != 1) ++num;
return num == 2;
}
int main() {
int n;
while (scanf ("%d", &n) != EOF) {
int res = 0;
for (int i = 6; i <= n; ++i)
res += check(i);
printf ("%d\n", res);
}
return 0;
}
D题:大概就是一个括号匹配吧。
可以用stack搞,貌似貌似这里计数就可以了,这道题我反正是想复杂了。这里给个很不错的解法,见CODE。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
const int MAXN = 1001000;
char s[MAXN];
int main()
{
scanf("%s", s);
int cnt = 0;
int sc = 0;
for(int i = 0; s[i]; ++i)
{
if (s[i] == '(')
{
sc++;
cnt++;
}
else
{
if (sc > 0)
{
sc--;
cnt++;
}
}
}
cnt -= sc;
printf("%d\n", cnt);
return 0;
}
E题:统计2到n区间内的数,该数可以分解为两个素数和+1。如果这样的数字个数大于等于k Yes 否则 NO。
统计区间满足这样情况的数,然后check一下。这里可以直接把范围内的数字打表出来,然后对应输入check输出答案即可
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
int ans[1005], prime[1005];
int is_prime(int n)
{
for (int i = 2; i <= sqrt(n); ++i)
if(n % i == 0)
return 0;
return 1;
}
int init()
{
int k = 0;
memset(ans, 0, sizeof(ans));
for (int i = 2; i <= 1000; ++i)
if(is_prime(i))
prime[k++] = i;
for (int i = 0; i < k-1; ++i) {
int m = prime[i]+prime[i+1]+1;
if(is_prime(m))
ans[m]++;
}
for (int i = 1; i <= 1000; ++i)
ans[i] += ans[i-1];
return 0;
}
int main()
{
// freopen("a.in", "r", stdin);
// freopen("a.out", "w", stdout);
init();
int n, k;
cin >> n >> k;
if(ans[n] >= k)
cout << "YES" << endl;
else
cout << "NO" << endl;
return 0;
}
F题:这题是求一个类似最小生成树的东西。但是是有限制的MST。
预处理的时候就把数据处理一下,然后按照kruskal算法的思路搞下来。不太好讲,估计得你们自己啃下这题。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Node
{
int a,b;
int cost;
}node[10010];
bool cmp(Node a,Node b)
{
return a.cost<b.cost;
}
bool f[1010];
int v[1010];
int main()
{int n,m,a,b,c;
while(cin>>n)
{memset(node,0,sizeof(node));
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
scanf("%d",&v[i]);
cin>>m;
int num=0;
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
if(v[a]>v[b])
{
node[num].a=a;
node[num].b=b;
node[num++].cost=c;
}
}
sort(node,node+num,cmp);
long long ans=0;
int num1=0;
for(int i=0;i<num;i++)
{
if(!f[node[i].b])
{
ans+=node[i].cost;
f[node[i].b]=1;
num1++;
}
}
if(num1==n-1)
{
cout<<ans<<endl;
}
else cout<<"-1"<<endl;
}
return 0;
}