There's the conditional_fields module, which sounds like it'll get you most of the way there.
Failing that, I'd say your best bet is to use hook_form_alter() in a custom module.
Something like:
function yourmodule_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'user_register') {
// Define the phone field.
$form['phone'] = array(
'#type' => 'textfield',
'#title' => t('Phone'),
'#size' => 30,
'#maxlength' => 30,
'settings' => array(
'#states' => array(
// Hide this field when role A isn't checked.
'invisible' => array(
':input[role="A"]' => array('checked' => FALSE),
),
),
),
);
// Define home address field
// [copy the snippet above & tweak to suit...]
}
}
This is unlikely to work out of the box (I've no drupal environment to hand), but with some adaptation it should get you most of the way there.
The "':input[role="A"]' => array('checked' => TRUE)," line will need the most work, i.e. "role" will need to match the name attribute of the "Roles" checkboxes, and the "A" will need to correspond to A's actual value when checked.
If you've no other form_alter usage in your module, you might also consider replacing the function name with "yourmodule_user_register_form_alter".