F题有很较强的技巧性,将每一个单词拆分成所有可能的前缀,并且这些前缀每次出现其作为键对应的值就加一,当所有的单词都这样操作过后,map中就记录了所有可能的键对应的值。
例如 banana会被拆分为 banan bana ban ba b.
#include <bits/stdc++.h>
using namespace std;
int main()
{
char s1[20], s2[20];
map<string, int> ma;
while( gets(s1), s1[0] != '\0' )
{
for( int i=strlen(s1); i>=0; i-- )
{
s1[i] = '\0';
ma[s1]++;
}
}
while( gets(s2) )
printf("%d\n", ma[s2] );
return 0;
}
G题是去除一列数中重复的数字,且不改变原来的顺序。思路就是利用set的去重性和一个数组来保存输入的数,然后从头遍历数组,每次输出判断该数是否已经在set出现过,没有就输出并添加进set,如果出现过就跳过该数的输出。
int num[50000+5];
set<int> s;
int main()
{
int t, n;
scanf("%d", &t );
while( t-- )
{
scanf("%d", &n );
for( int i=0; i<n; i++ )
scanf("%d", &num[i] );
for( int i=0; i<n; i++ )
{
if( !s.count(num[i]) )
{
printf("%d ", num[i] );
s.insert(num[i]);
}
}
printf("\n");
s.clear();
}
H题的思路为分别用三个数组存起来三组数,排序后一 一对应的比较,如果出现不同的则前一个数组在该位置的数就是被改正的序号。第二个思路是把每一个数组的和加起来,然后第一个数组减去第二个数组就是第一个被改正的序号,同理第二个数组减去第三个数组就是第二个被改正的序号。
int num1[100000+5];
int num2[100000+5];
int num3[100005+5];
int main()
{
int n;
while( scanf("%d", &n ) != EOF )
{
memset(num1, 0, sizeof(num1));
memset(num2, 0, sizeof(num2));
memset(num3, 0, sizeof(num3));
for( int i=0; i<n; i++ )
scanf("%d", &num1[i] );
for( int i=0; i<n-1; i++ )
scanf("%d", &num2[i] );
for( int i=0; i<n-2; i++ )
scanf("%d", &num3[i] );
sort( num1, num1+n );
sort( num2, num2+n-1 );
sort( num3, num3+n-2 );
for( int i=0; i<n; i++ )
{
if( num1[i] != num2[i] )
{
printf("%d\n", num1[i] );
break;
}
}
for( int i=0; i<n-1; i++ )
{
if( num2[i] != num3[i] )
{
printf("%d\n", num2[i] );
break;
}
}
}
I 题 要注意的是题目要求sum1和sum3相等且在求和的过程中不能改变原来数列顺序,也就是说不能排序。
思路是sum1和sum3从两边开始求和,每次都比较sum1和sum3的值,直到数组从左边开始的下标大于从右边开始的下标。
注意要用long long.
vector<LL> ve;
int main()
{
int n;
LL number;
while( scanf("%lld", &n ) != EOF )
{
for( int i=0; i<n; i++ )
{
scanf("%lld", &number );
ve.push_back(number);
}
LL sum1, sum2, sum3;
int i, j;
i = 0, j = n-1;
sum1 = ve[0], sum3 = ve[n-1];
sum2 = 0;
while( i<j )
{
if( sum1 == sum3 )
sum2 = sum1;
if( sum1 < sum3 )
{
sum1 += ve[i+1];
i++;
}
else
{
sum3 += ve[j-1];
j--;
}
}
printf("%lld\n", sum2 );
ve.clear();
}