招行信用卡中心开发编程题解

还挺晚的..20:30才开始
选择题分很多而且几乎不会,Java,sql啥的...凉了一大半..
3个编程,有点codeforce题目的感觉,看着觉得难,其实没什么厉害的算法就是不好想。

第一题给一串LR组成的字符串,每个位置一个机器人,每个机器人在L就往左走1步在R就往右1步。问10^100步后每个格子有几个机器人。保证最左的格子是R最右的格子是L。
10^100挺吓人的..其实知道这是一个很大的偶数就可以。
发现每个机器人必定走入一个LR或RL循环,所以只要记录:当前位置左边的第一个R和当前位置右边的第一个L,就知道机器人在哪个循环里。
然后判断一下奇偶,就知道最后机器人在循环里的L还是R。线性过3遍,复杂度O(n)
#include <bits/stdc++.h>
using namespace std;
#define LL long long
char ss[100005];
int l[100005];
int r[100005];
int ans[100005];
int main()
{
	int i, j;
	int n;
	while (~scanf("%s", ss))
	{
		n = strlen(ss);
		for (i = 0; i < n; i++)
			if (ss[i] == 'R')
				r[i] = i;
			else
				r[i] = r[i - 1];
		for (i = n - 1; i >= 0; i--)
			if (ss[i] == 'L')
				l[i] = i;
			else
				l[i] = l[i + 1];
		for (i = 0; i < n; i++)
		{
			int count;
			if (ss[i] == 'R')
			{
				count = l[i] - i;
				if (count % 2 == 0)
					ans[l[i]]++;
				else
					ans[l[i] - 1]++;
			}
			else//L
			{
				count = i - r[i];
				if (count % 2 == 0)
					ans[r[i]]++;
				else
					ans[r[i] + 1]++;
			}
		}
			printf("%d",ans[0]);
			for (i = 1; i < n; i++)
				printf(" %d", ans[i]);
			puts("");
	}
	return 0;
}

第二题给一个树,1是根节点,有边权,可能是负数,求什么来着..好像是求每个点构成的子树里,从根出发最长的路径(可以没有路径,所以至少是0)节点数20W
求的啥记不清了,反正dp的是dp[当前节点]=max(dp[子节点]+路径权),遍历一遍树就行
重点是存边的方式吧..用的acm里的方法,链表vector那种存也行,别二维数组..
好多人这题没过..不太记得有啥要点了..别开N*N的二维数组..存双向边,存答案用longlong..
#include <bits/stdc++.h>
using namespace std;
#define LL long long
struct { int v, w, ne; }a[200005 << 1];
int h[200005];
int k;
int vi[200005];
LL ans[200005];
void add(int u, int v, int w)//初始k=1
{
	a[k].v = v, a[k].w = w, a[k].ne = h[u], h[u] = k++;
}
LL dfs(int u)
{
	if (vi[u] == 1)
		return ans[u];
	vi[u] = 1;
	for (int i = h[u]; i; i = a[i].ne)
	{
		LL temp = a[i].w;
		
		if (vi[a[i].v] == 0)
			ans[u] = max(ans[u], temp + dfs(a[i].v));
	}
	return ans[u];
}

int main()
{
	int i, j;
	int n;
	while (~scanf("%d", &n))
	{
		k = 1;
		for (i = 1; i < n; i++)
		{
			int x, y, z;
			scanf("%d%d%d", &x, &y, &z);
			add(x, y, z);
			add(y, x, z);
		}
		printf("%lld", dfs(1));

		for (i = 2; i <= n; i++)
			printf(" %lld",dfs(i));
		puts("");
	}
	return 0;
}


第三个,给一个数字和?构成的字符串,?可以填0-9,求有几种可能让填成的数%13=5,允许有前导0,答案%1e9+7
以为是数论排列组合啥的,想了好久,其实dp一下就行..
思想是记录当前位之前构成的串%13的13种值的个数,后面加一个数字,就是a*10+b这种的转移,对取模也是一样的。
转移方程就是dp1[(10*j+k)%13]+=dp0[j]。dp0是先前的数组,dp1是空的,新的数组。j取0到12,k取当前数位,?就取0-9。(滚动数组节约内存,但没必要..)
#include <bits/stdc++.h>
using namespace std;
#define LL long long
LL mm = 1000000007;
char ss[100005];
LL dp0[15], dp1[15];
int main()
{
	int i, j, k;
	int n;

	while (~scanf("%s", ss))
	{
		n = strlen(ss);
		memset(dp0, 0, sizeof(dp0));
		memset(dp1, 0, sizeof(dp1));
		if (ss[0] == '?')
			for (i = 0; i < 10; i++)
				dp0[i] = 1;
		else
			dp0[ss[0] - '0'] = 1;
		for (i = 1; i < n; i++)
		{
			for (j = 0; j < 13; j++)
			{
				if (ss[i] == '?')
					for (k = 0; k < 10; k++)
					{
						dp1[(10 * j + k) % 13] += dp0[j];
						dp1[(10 * j + k) % 13] %= mm;
					}
				else
				{
					dp1[(10 * j + ss[i] - '0') % 13] += dp0[j];
					dp1[(10 * j + ss[i] - '0') % 13] %= mm;
				}
			}
			memcpy(dp0, dp1, sizeof(dp0));
			memset(dp1, 0, sizeof(dp1));
		}
		printf("%lld\n",dp0[5]);
	}
	return 0;
}







#笔试题目#
全部评论
太强了
点赞 回复
分享
发布于 2019-09-15 22:37
太强了
点赞 回复
分享
发布于 2019-09-15 22:39
联易融
校招火热招聘中
官网直投
太强了
点赞 回复
分享
发布于 2019-09-15 22:40
太强了
点赞 回复
分享
发布于 2019-09-15 22:41
tql
点赞 回复
分享
发布于 2019-09-15 22:43
tql
点赞 回复
分享
发布于 2019-09-15 22:44
太强了
点赞 回复
分享
发布于 2019-09-15 22:46
太强了
点赞 回复
分享
发布于 2019-09-15 22:47
tql
点赞 回复
分享
发布于 2019-09-15 22:47
大佬。。。
点赞 回复
分享
发布于 2019-09-15 22:47
大佬,请收下小弟的膝盖
点赞 回复
分享
发布于 2019-09-15 22:48
tql
点赞 回复
分享
发布于 2019-09-15 22:50
在收下另一个膝盖!
点赞 回复
分享
发布于 2019-09-15 22:51
第二题你这代码过了?
点赞 回复
分享
发布于 2019-09-15 22:53
能不能请大佬 在讲下第三个  没看懂
点赞 回复
分享
发布于 2019-09-15 23:06
第三题用dfs只过了0.2 有什么区别吗……
点赞 回复
分享
发布于 2019-09-15 23:24
大佬搞过ACM的吗
点赞 回复
分享
发布于 2019-09-15 23:27
tql
点赞 回复
分享
发布于 2019-09-15 23:30
真的太厉害了(ง •̀_•́)ง
点赞 回复
分享
发布于 2019-09-15 23:31
第二题,每个结点 U 到子树中某结点 V 的最大边权和,有大佬帮我看看吗? import java.util.*; public class Main {     static int [] dparray_weight; //每个结点 U 到子树中某结点 V 的最大边权和     static int [][] tree_edge; //记录边的权值     static int n;  //结点个数     public static void main(String[] args) {         Scanner sc = new Scanner(System.in);         n = Integer.valueOf(sc.nextLine());         tree_edge = new int[n][n];         dparray_weight = new int[n];         init_tree_edge(); //初始化边矩阵,自己到自己为0,其余为int的最大值         //保存输入的边         for(int i=1;i<n;i++){             String[] temp = sc.nextLine().split(" ");             int u = Integer.valueOf(temp[0])-1;             int v=  Integer.valueOf(temp[1])-1;             tree_edge[u][v] = Integer.valueOf(temp[2]);         }         dp_weight(0);         for(int i=0;i<n;i++)             System.out.print(dparray_weight[i]+" ");     }     public static int dp_weight(int index){         if( isleaf(index) ){             dparray_weight[index]=0;             return  dparray_weight[index];         }         for(int j=0;j<n;j++)             if( j!=index && tree_edge[index][j] != Integer.MAX_VALUE ) //index到j有一条边                 dparray_weight[index]=Math.max(dparray_weight[index], dp_weight(j)+ tree_edge[index][j]);         return  dparray_weight[index];     }     public static boolean isleaf(int index){ //结点下标为index的结点是不是叶子结点         boolean flag =true;         for(int j=0;j<n;j++)             if( tree_edge[index][j] != Integer.MAX_VALUE && index!=j){                 flag = false;                 break;             }         return flag;     }     public static void init_tree_edge(){         for(int i=0;i<n;i++)             for (int j=0;j<n;j++)                 if(i==j)                     tree_edge[i][j]=0;                 else                     tree_edge[i][j]=  Integer.MAX_VALUE;     }     public static void print_array(){         for(int i=0;i<n;i++){             for (int j=0;j<n;j++)                 System.out.print(tree_edge[i][j]+" ");             System.out.println();         }     } }
点赞 回复
分享
发布于 2019-09-15 23:48

相关推荐

27 148 评论
分享
牛客网
牛客企业服务